Advertisement
Guest User

main.ino

a guest
Apr 23rd, 2025
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.89 KB | None | 0 0
  1. #include <ESP8266WiFi.h>
  2. #include <WiFiClient.h>
  3. #include <ESP8266WebServer.h>
  4. #include <ESP8266mDNS.h>
  5. #include <uri/UriBraces.h>
  6. #include <uri/UriRegex.h>
  7. #include "index.h"
  8. #include <HCSR04.h>
  9. #include <L298N.h>
  10.  
  11.  
  12.  
  13. #define DEBUG
  14.  
  15. /* WiFi configuration */
  16. #ifndef STASSID
  17. #define STASSID "Antonio" // PUT YOUR "WIFI NAME" HERE
  18. #define STAPSK "11223344" // PUT YOUR WIFI PASSWORD HERE
  19. #define OPT_HOSTNAME "table" // Optional hostname
  20. #endif
  21. const char *SSID = STASSID;
  22. const char *PASSWORD = STAPSK;
  23. const char *HOSTNAME = OPT_HOSTNAME;
  24.  
  25. /* Pin configuration */
  26. #define IN1 2
  27. #define IN2 0
  28. #define ULTRASONIC_SENSOR_ECHO_PIN 5 // HC-SR04 ultrasonic sensor - Echo Pin
  29. #define ULTRASONIC_SENSOR_TRIGGER_PIN 4 // HC-SR04 ultrasonic sensor - Trigger Pin
  30.  
  31. /* Configure ESP8266 web server */
  32. ESP8266WebServer server(80); // use port 80
  33.  
  34. /* Configure the motor driver */
  35. L298N motor(IN1, IN2);
  36.  
  37. /* Configure ultrasonic sensor */
  38. HCSR04 hc(ULTRASONIC_SENSOR_TRIGGER_PIN, ULTRASONIC_SENSOR_ECHO_PIN); // initialisation HCSR04 (ultrasonic sensor) (trig pin , echo pin)
  39.  
  40. /* States of the system */
  41. typedef enum {
  42. UP, // table is supposed to go up
  43. DOWN, // table is supposed to go down
  44. HOLD, // table is supposed to do nothing -> hold still
  45. CUSTOM_HEIGHT // table goes up/down and holds as soon as it reached the custom height
  46. } state_t;
  47.  
  48. /* Global state of the system. In HOLD by default -> motor will not move in this state */
  49. state_t g_system_state = HOLD; //
  50.  
  51. /* Maximum and minimum height of the table in cm */
  52. const unsigned int MOTOR_CASE_HEIGHT = 5; /* 5 cm */
  53. const unsigned int TABLE_THICKNESS = 2; /* approx. 2 cm */
  54. const unsigned int HEIGHT_DIFFERENCE = MOTOR_CASE_HEIGHT + TABLE_THICKNESS;
  55. const unsigned int MAX_HEIGHT = 120;/* 120 cm is the offical maximum height from the IKEA manual */
  56. const unsigned int MIN_HEIGHT = 70; /* 70 cm is the offical minimum height from the IKEA manual */
  57.  
  58. /* Height tolerance (in cm) which is needed because the ultrasonic sensor is not really accurate */
  59. const unsigned int HEIGHT_TOLERANCE = 2; /* This used to be 5 cm but was reduced to 2 because of how slow the table motor is */
  60.  
  61. /* Global variable which shall hold the wanted custom height when requested */
  62. int g_custom_height;
  63.  
  64.  
  65. /*
  66. * Displays the index/main page in the browser of the client
  67. */
  68. void display_index() {
  69. String s = MAIN_page; // read HTML contents from the MAIN_page variable which was stored in the flash (program) memory instead of SRAM, see index.h
  70. server.send(200, "text/html", s); // send web page
  71. }
  72.  
  73.  
  74. /*
  75. * The server sends a redirection response to the client so it will go back to the homepage after requesting a state change,
  76. * e.g. when motor up was clicked it shall go back to the homepage
  77. */
  78. void send_homepage_redirection() {
  79. server.sendHeader("Location","/"); // Client shall redirect to "/"
  80. server.send(303);
  81. }
  82.  
  83.  
  84. /*
  85. * Handles calls to the URI /motor/<string: action>/ and does state transitions:
  86. * if for example /motor/up is called, then the system will transition from the previous state
  87. * to the state UP.
  88. */
  89. void handle_motor_requests() {
  90. String action = server.pathArg(0); // retrieve the given argument/action
  91.  
  92. if(action == "up"){
  93. g_system_state = UP;
  94. }
  95. else if(action == "stop"){
  96. g_system_state = HOLD;
  97. }
  98. else if(action == "down"){
  99. g_system_state = DOWN;
  100. }
  101. else {
  102. Serial.println("Error: Action is unknown"); // system will stay in its previous state
  103. }
  104.  
  105. // send response
  106. send_homepage_redirection();
  107. }
  108.  
  109.  
  110. /*
  111. * Handles calls to the URI /height/<string: height_in_cm>/
  112. * If a height is given, then the system shall transition into the CUSTOM_HEIGHT state.
  113. */
  114. void handle_height_requests() {
  115. int height = atoi((server.pathArg(0)).c_str()); // convert string parameter to integer
  116.  
  117. // only change the state if the given height is in the height boundaries
  118. if(height >= MIN_HEIGHT and height <= MAX_HEIGHT) {
  119. g_custom_height = height; // set the custom height
  120. g_system_state = CUSTOM_HEIGHT; // transition to the custom height state
  121. }
  122.  
  123. // send response
  124. send_homepage_redirection();
  125. }
  126.  
  127.  
  128. /*
  129. * Handles calls to the URI /height/
  130. * Responds with the current height of the ultrasonic sensor
  131. */
  132. void handle_read_height_requests() {
  133. int height = get_current_height();
  134. Serial.print("Sending height: ");
  135. Serial.println(height); // Should match the Serial Monitor output
  136. String heightStr = String(height);
  137. Serial.print("Height as string: ");
  138. Serial.println(heightStr); // Verify the string conversion
  139. server.send(200, "text/plain", heightStr);
  140. }
  141.  
  142.  
  143.  
  144.  
  145. /**
  146. * Setup the output pins
  147. */
  148. void setup_pins() {
  149. // Pin setup for motor controller
  150. pinMode(IN1, OUTPUT);
  151. pinMode(IN2, OUTPUT);
  152. }
  153.  
  154.  
  155. /**
  156. * Takes care of the wifi configuration
  157. */
  158. void setup_wifi() {
  159. WiFi.mode(WIFI_STA);
  160. WiFi.hostname(OPT_HOSTNAME); // set HOSTNAME
  161. WiFi.begin(SSID, PASSWORD);
  162.  
  163. // Wait for wifi connection
  164. while (WiFi.status() != WL_CONNECTED) {
  165. delay(500);
  166. Serial.print(".");
  167. }
  168.  
  169. // Start the mDNS responder for esp8266.local
  170. if (MDNS.begin("esp8266")) {
  171. Serial.println("MDNS responder started");
  172. }
  173. }
  174.  
  175.  
  176. /**
  177. * Print information about the wifi connection:
  178. * SSID, IP, HOSTNAME
  179. */
  180. void print_connection_info() {
  181. // Print connection info
  182. Serial.print("Connected to ");
  183. Serial.println(SSID);
  184. Serial.print("IP address: ");
  185. Serial.println(WiFi.localIP());
  186. Serial.print("HOSTNAME: ");
  187. Serial.println(WiFi.hostname().c_str());
  188. }
  189.  
  190.  
  191. /**
  192. * Register the routes of the server
  193. */
  194. void register_server_routes() {
  195. server.on(F("/"), display_index); // route: /
  196. server.on(UriBraces("/motor/{}"), handle_motor_requests); // route: /motor/<string: action>/
  197. server.on(UriBraces("/height/{}"), handle_height_requests); // route: /height/<string: height_in_cm>/
  198. server.on(UriBraces("/height"), handle_read_height_requests); // route: /height/ - is being called from client javascript
  199. }
  200.  
  201.  
  202. /*
  203. * Login to the network, setup the server and register URI call handlers.
  204. */
  205. void setup(void) {
  206. Serial.begin(115200);
  207.  
  208. setup_wifi();
  209.  
  210. #ifdef DEBUG
  211. print_connection_info();
  212. #endif
  213.  
  214. register_server_routes();
  215.  
  216. // Start the server
  217. server.begin();
  218. Serial.println("HTTP server started");
  219. }
  220.  
  221.  
  222. /*
  223. * Retrieves the current height of the table by getting the distance of the
  224. * ultrasonic sensor.
  225. */
  226. int get_current_height() {
  227. delay(100);
  228. int distance = hc.dist();
  229. Serial.print("Raw distance from sensor: ");
  230. Serial.println(distance); // Print the raw distance
  231. Serial.print("HEIGHT_DIFFERENCE: ");
  232. Serial.println(HEIGHT_DIFFERENCE); // Print the HEIGHT_DIFFERENCE
  233. int height = distance + HEIGHT_DIFFERENCE;
  234. Serial.print("Calculated height: ");
  235. Serial.println(height); // Print the calculated height
  236. return height;
  237. }
  238.  
  239.  
  240.  
  241. /*
  242. * Raise the table until the max height is reached
  243. */
  244. void raise_table() {
  245. if(MAX_HEIGHT >= get_current_height()) {
  246. motor.forward();
  247. }
  248. else {
  249. g_system_state = HOLD;
  250. }
  251. }
  252.  
  253.  
  254. /*
  255. * Lower the table until the min height is reached
  256. */
  257. void lower_table() {
  258. if(MIN_HEIGHT <= get_current_height()) {
  259. motor.backward();
  260. }
  261. else {
  262. g_system_state = HOLD;
  263. }
  264. }
  265.  
  266.  
  267. /*
  268. * Stop the table at the current height
  269. */
  270. void stop_table() {
  271. motor.stop();
  272. }
  273.  
  274.  
  275. /*
  276. * Controls the motor based on the system state g_system_state. This is pretty much the core FSM implementation for the state transistions.
  277. */
  278. void handle_output() {
  279. switch (g_system_state) {
  280. case UP:
  281. raise_table(); // motor go up
  282. break;
  283. case DOWN:
  284. lower_table(); // motor go down
  285. break;
  286. case HOLD:
  287. stop_table(); // stop the motor
  288. break;
  289. case CUSTOM_HEIGHT:
  290. // adjust the table height until the height tolerance is ok, e.g.: abs(150-130) = 20, abs(150-170) = 20
  291. if(abs(g_custom_height - get_current_height()) >= HEIGHT_TOLERANCE) {
  292. // check if the table is too high or too low and adjust
  293. if(g_custom_height < get_current_height()) {
  294. lower_table(); // lower the table
  295. }
  296. else{
  297. raise_table(); // raise the table
  298. }
  299.  
  300. }
  301. else {
  302. // adjustment is finished, transistion to the hold state to stop the motor
  303. g_system_state = HOLD;
  304. }
  305.  
  306. break;
  307. default:
  308. // stop the motor by transitioning to the hold state
  309. g_system_state = HOLD;
  310. }
  311. }
  312.  
  313.  
  314. /*
  315. * Main loop. Gets the current height, retrieves inputs and do state
  316. * transitions and finally control the motor based on the state.
  317. */
  318. void loop(void) {
  319. server.handleClient(); // gets input from a client
  320. handle_output(); // controls the height of the table based on the input
  321. }
  322.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement