NodeMCU
Hall Sensor Module
Neodymium Magnets (2)
16X2 LCD Display
Momentary Buttons (2)
10K Resistor (2)
1K Resistor (1)
10K Potentiometer
USB Female Module
5V 2A Power Supply
- // toilet paper sheet counter
- // pkvi
- #include <LiquidCrystal.h>
- #include <ESP8266WiFi.h>
- #include "MapFloat.h"
- // display
- LiquidCrystal lcd(D6, D5, D4, D3, D2, D1);
- // sensor
- const int hall = D7;
- int hs, hn;
- // button
- const int b_left = D0;
- const int b_right = D8;
- int bl, br;
- // states
- int new_roll, total_sheets, sheets_left;
- int pull_now, last_pull, pull_total;
- long pull_value, passed;
- long hold = 300000; // 5 minutes
- // wifi
- const char* ssid = "yourssid";
- const char* password = "yourpass";
- WiFiServer server(80);
- // thingspeak
- char thingSpeakAddress[] = "api.thingspeak.com";
- String APIKey = "yourapikey"; // API
- const int updateThingSpeakInterval = 10 * 1000;
- long lastConnectionTime = 0;
- boolean lastConnected = false;
- WiFiClient client;
- void setup() {
- Serial.begin(115200);
- lcd.begin(16, 2);
- lcd.setCursor(0, 0);
- lcd.print("Toilet Paper");
- lcd.setCursor(0, 1);
- lcd.print("Sheet Counter");
- delay(1500);
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("Connecting...");
- while (WiFi.status() != WL_CONNECTED) {
- WiFi.begin(ssid, password);
- delay(10000);
- }
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("Connected");
- server.begin();
- delay(1000);
- lcd.clear();
- pinMode(b_left, INPUT);
- pinMode(b_right, INPUT);
- pinMode(hall, INPUT);
- }
- void loop() {
- // new roll setting
- if (new_roll == 0) {
- select_roll();
- }
- // read roll
- hs = digitalRead(hall);
- if (hs == LOW) {
- // to isolate requests
- if (hn == 0) {
- // spiral maths
- pull_value = mapFloat(pull_total, 0, total_sheets, 2.25, 0.5);
- pull_value = round(pull_value); // this ruins it
- pull_now = pull_now + pull_value;
- pull_total = pull_total + pull_value;
- sheets_left = total_sheets - pull_total;
- update_display();
- // states
- passed = 0;
- hn = 1;
- }
- } else {
- hn = 0;
- }
- // dont count time if inactive
- if (pull_now != 0) {
- passed++;
- Serial.println(passed);
- }
- // send and reset
- if (passed > hold) {
- net_send();
- last_pull = pull_now;
- pull_now = 0;
- passed = 0;
- lcd.setCursor(5, 0);
- lcd.print(" ");
- lcd.setCursor(5, 1);
- lcd.print(" ");
- update_display();
- }
- // end of roll
- if (sheets_left < 1) {
- new_roll = 0;
- }
- // reset roll button
- br = digitalRead(b_right);
- if (br == HIGH) {
- new_roll = 0;
- delay(700);
- }
- }
- void select_roll() {
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("Select Sheets");
- total_sheets = 200;
- while (digitalRead(b_right) == LOW) {
- lcd.setCursor(0, 1);
- lcd.print(total_sheets);
- bl = digitalRead(b_left);
- if (bl == HIGH) {
- total_sheets = total_sheets + 5;
- delay(100);
- }
- yield(); // esp fix
- }
- last_pull = 0;
- pull_total = 0;
- pull_now = 0;
- sheets_left = total_sheets;
- new_roll = 1;
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("Last");
- lcd.setCursor(5, 0);
- lcd.print(last_pull);
- lcd.setCursor(10, 0);
- lcd.print("(+");
- lcd.setCursor(12, 0);
- lcd.print(pull_total);
- lcd.setCursor(15, 0);
- lcd.print(")");
- lcd.setCursor(0, 1);
- lcd.print("Now");
- lcd.setCursor(5, 1);
- lcd.print(pull_now);
- lcd.setCursor(10, 1);
- lcd.print("(-");
- lcd.setCursor(12, 1);
- lcd.print(sheets_left);
- lcd.setCursor(15, 1);
- lcd.print(")");
- delay(500);
- }
- void update_display() {
- lcd.setCursor(5, 0);
- lcd.print(last_pull);
- lcd.setCursor(12, 0);
- lcd.print(pull_total);
- lcd.setCursor(5, 1);
- lcd.print(pull_now);
- lcd.setCursor(12, 1);
- lcd.print(sheets_left);
- }
- void net_send() {
- String last_sheet = String(pull_now, DEC);
- String last_total = String(pull_total, DEC);
- updateThingSpeak("field1=" + last_sheet + "&field2=" + last_total);
- delay(3000);
- }
- void updateThingSpeak(String tsData) {
- if (client.connect(thingSpeakAddress, 80)) {
- client.print("POST /update HTTP/1.1\n");
- client.print("Host: api.thingspeak.com\n");
- client.print("Connection: close\n");
- client.print("X-THINGSPEAKAPIKEY: " + APIKey + "\n");
- client.print("Content-Type: application/x-www-form-urlencoded\n");
- client.print("Content-Length: ");
- client.print(tsData.length());
- client.print("\n\n");
- client.print(tsData);
- }
- }