Keep track of use and abuse. Whose butt does the most damage to the planet and budget?!VIDEO
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 ThingSpeakhttps://thingspeak.com/channels/1631806 Sheet count maps to average per rotation per total use. The formula is determined by average count of (4) sheets per complete exterior rotation and (1) sheet per complete interior rotation. Primary error in accuracy will be found in the round() function for display purposes. If you were to remove the display or isolate the values from each other then you would have results different than displayed. If you display decimal values then it becomes untidy. ~(°-°)~ (322.021) Code updated to repair missing reset zeroing.// toilet paper sheet counter // vije miller #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); } }