NodeMCU WiFi Toilet Paper Sheet Counter

files.catbox.moe/m08bl4.mp4
tiktok.com/@vgmllr/video/7352930260389776683

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



  1. // toilet paper sheet counter
  2. // vgmlr
  3. #include "LiquidCrystal.h"
  4. #include "ESP8266WiFi.h"
  5. #include "MapFloat.h"
  6. // display
  7. LiquidCrystal lcd(D6, D5, D4, D3, D2, D1);
  8. // sensor
  9. const int hall = D7;
  10. int hs, hn;
  11. // button
  12. const int b_left = D0;
  13. const int b_right = D8;
  14. int bl, br;
  15. // states
  16. int new_roll, total_sheets, sheets_left;
  17. int pull_now, last_pull, pull_total;
  18. long pull_value, passed;
  19. long hold = 300000; // 5 minutes
  20. // wifi
  21. const char* ssid = "yourssid";
  22. const char* password = "yourpass";
  23. WiFiServer server(80);
  24. // thingspeak
  25. char thingSpeakAddress[] = "api.thingspeak.com";
  26. String APIKey = "yourapikey"; // API
  27. const int updateThingSpeakInterval = 10 * 1000;
  28. long lastConnectionTime = 0;
  29. boolean lastConnected = false;
  30. WiFiClient client;
  31. void setup() {
  32. Serial.begin(115200);
  33. lcd.begin(16, 2);
  34. lcd.setCursor(0, 0);
  35. lcd.print("Toilet Paper");
  36. lcd.setCursor(0, 1);
  37. lcd.print("Sheet Counter");
  38. delay(1500);
  39. lcd.clear();
  40. lcd.setCursor(0, 0);
  41. lcd.print("Connecting...");
  42. while (WiFi.status() != WL_CONNECTED) {
  43. WiFi.begin(ssid, password);
  44. delay(10000);
  45. }
  46. lcd.clear();
  47. lcd.setCursor(0, 0);
  48. lcd.print("Connected");
  49. server.begin();
  50. delay(1000);
  51. lcd.clear();
  52. pinMode(b_left, INPUT);
  53. pinMode(b_right, INPUT);
  54. pinMode(hall, INPUT);
  55. }
  56. void loop() {
  57. // new roll setting
  58. if (new_roll == 0) {
  59. select_roll();
  60. }
  61. // read roll
  62. hs = digitalRead(hall);
  63. if (hs == LOW) {
  64. // to isolate requests
  65. if (hn == 0) {
  66. // spiral maths
  67. pull_value = mapFloat(pull_total, 0, total_sheets, 2.25, 0.5);
  68. pull_value = round(pull_value); // this ruins it
  69. pull_now = pull_now + pull_value;
  70. pull_total = pull_total + pull_value;
  71. sheets_left = total_sheets - pull_total;
  72. update_display();
  73. // states
  74. passed = 0;
  75. hn = 1;
  76. }
  77. } else {
  78. hn = 0;
  79. }
  80. // dont count time if inactive
  81. if (pull_now != 0) {
  82. passed++;
  83. Serial.println(passed);
  84. }
  85. // send and reset
  86. if (passed > hold) {
  87. net_send();
  88. last_pull = pull_now;
  89. pull_now = 0;
  90. passed = 0;
  91. lcd.setCursor(5, 0);
  92. lcd.print(" ");
  93. lcd.setCursor(5, 1);
  94. lcd.print(" ");
  95. update_display();
  96. }
  97. // end of roll
  98. if (sheets_left < 1) {
  99. new_roll = 0;
  100. }
  101. // reset roll button
  102. br = digitalRead(b_right);
  103. if (br == HIGH) {
  104. new_roll = 0;
  105. delay(700);
  106. }
  107. }
  108. void select_roll() {
  109. lcd.clear();
  110. lcd.setCursor(0, 0);
  111. lcd.print("Select Sheets");
  112. total_sheets = 200;
  113. while (digitalRead(b_right) == LOW) {
  114. lcd.setCursor(0, 1);
  115. lcd.print(total_sheets);
  116. bl = digitalRead(b_left);
  117. if (bl == HIGH) {
  118. total_sheets = total_sheets + 5;
  119. delay(100);
  120. }
  121. yield(); // esp fix
  122. }
  123. last_pull = 0;
  124. pull_total = 0;
  125. pull_now = 0;
  126. sheets_left = total_sheets;
  127. new_roll = 1;
  128. lcd.clear();
  129. lcd.setCursor(0, 0);
  130. lcd.print("Last");
  131. lcd.setCursor(5, 0);
  132. lcd.print(last_pull);
  133. lcd.setCursor(10, 0);
  134. lcd.print("(+");
  135. lcd.setCursor(12, 0);
  136. lcd.print(pull_total);
  137. lcd.setCursor(15, 0);
  138. lcd.print(")");
  139. lcd.setCursor(0, 1);
  140. lcd.print("Now");
  141. lcd.setCursor(5, 1);
  142. lcd.print(pull_now);
  143. lcd.setCursor(10, 1);
  144. lcd.print("(-");
  145. lcd.setCursor(12, 1);
  146. lcd.print(sheets_left);
  147. lcd.setCursor(15, 1);
  148. lcd.print(")");
  149. delay(500);
  150. }
  151. void update_display() {
  152. lcd.setCursor(5, 0);
  153. lcd.print(last_pull);
  154. lcd.setCursor(12, 0);
  155. lcd.print(pull_total);
  156. lcd.setCursor(5, 1);
  157. lcd.print(pull_now);
  158. lcd.setCursor(12, 1);
  159. lcd.print(sheets_left);
  160. }
  161. void net_send() {
  162. String last_sheet = String(pull_now, DEC);
  163. String last_total = String(pull_total, DEC);
  164. updateThingSpeak("field1=" + last_sheet + "&field2=" + last_total);
  165. delay(3000);
  166. }
  167. void updateThingSpeak(String tsData) {
  168. if (client.connect(thingSpeakAddress, 80)) {
  169. client.print("POST /update HTTP/1.1\n");
  170. client.print("Host: api.thingspeak.com\n");
  171. client.print("Connection: close\n");
  172. client.print("X-THINGSPEAKAPIKEY: " + APIKey + "\n");
  173. client.print("Content-Type: application/x-www-form-urlencoded\n");
  174. client.print("Content-Length: ");
  175. client.print(tsData.length());
  176. client.print("\n\n");
  177. client.print(tsData);
  178. }
  179. }
Update(s)-
1. ptmr | 343025 [Changelog]
10:22 343 025
Dev-
1. TVShow (227) 'CSA'
2. Wedge (Miter) 1.0.0
3. TVShow (228) 'APT'
4. TVProgram (83) 'BXT'
11:51 339 025

Menu
Index
Engineering
Entertainment
Literature
Miscellaneous
Contact
Search
tiktok.com/@vgmlr
youtube.com/@vgmlr
Miter
@vgmlr
=SUM(parts)
86 miters
131 tenons
Subscribe
0.00116