Hercules
main.cpp
Go to the documentation of this file.
1 #include <mbed.h>
2 #include "LCD_DISCO_F746NG.h"
3 #include "TS_DISCO_F746NG.h"
4 #include "DHT.h"
5 #include "display.h"
6 #include <iostream>
7 #include "stm32746g_discovery_sd.h"
8 #include "stm32746g_discovery_sdram.h"
9 #include "rtos.h"
10 #include "FileSystem.h"
11 
12 // Serial USB COM port
13 Serial usbCom(USBTX, USBRX);
14 
15 // LCD port
16 LCD_DISCO_F746NG lcd;
17 // LCD Touch port
18 TS_DISCO_F746NG ts;
19 
20 // On-board LED
21 DigitalOut led1(LED1);
22 // External LED (red)
23 DigitalOut led2(D2);
24 
25 // External buzzer
26 DigitalOut buzzer(D4);
27 
28 // External sensors
29 DHT dhtSensor(A0, SEN51035P);
30 AnalogIn vibrationSensor(A1);
31 AnalogIn lightSensor(A2);
32 AnalogIn soundSensor(A3);
33 
34 int currentView = 1;
35 int viewCount = 2;
36 
37 int tempScale = 0;
38 
39 // Touch Screen
40 TS_StateTypeDef TS_State;
41 uint16_t x, y;
42 uint8_t text[30];
43 uint8_t status;
44 uint8_t idx;
45 uint8_t cleared = 0;
46 uint8_t prev_nb_touches = 0;
47 
48 // Counter
49 int counter_max = 9999;
51 
54 
60 {
62  {
64 
66  {
67  counter_current = 0;
68  }
69  }
70 
71  char display_int[32];
72  sprintf(display_int, "Count: %04u", counter_current);
73 
74  if (1 == currentView)
75  {
76  lcd.DisplayStringAt(0, LINE(4), (uint8_t *)display_int, CENTER_MODE);
77  }
78 }
79 
80 // Display
81 
87 {
88  for (int i = 0; i <= 10; i++)
89  {
90  lcd.DisplayStringAt(0, LINE(i), (uint8_t *)" ", LEFT_MODE);
91  lcd.DisplayStringAt(0, LINE(i), (uint8_t *)" ", CENTER_MODE);
92  lcd.DisplayStringAt(0, LINE(i), (uint8_t *)" ", RIGHT_MODE);
93 
94  lcd.ClearStringLine(i);
95  }
96 
97  lcd.Clear(LCD_BACKGROUND);
98  lcd.SetBackColor(LCD_TEXT_BACKGROUND);
99  lcd.SetTextColor(LCD_TEXT_COLOR);
100 }
101 
102 // Sensors
103 
110 {
111  if (vibrationSensor.read() > 0.06)
112  {
113  led2 = 1;
114 
115  return 1;
116  }
117 
118  led2 = 0;
119 
120  return 0;
121 }
122 
128 {
129  int error = 0;
130  float h = 0.0f, c = 0.0f, d = 0.0f;
131 
132  error = dhtSensor.readData();
133  if (0 == error)
134  {
135  c = dhtSensor.ReadTemperature((eScale)tempScale);
136  h = dhtSensor.ReadHumidity();
137  d = dhtSensor.CalcdewPointFast(c, h);
138 
139  char temp[32];
140  char tempScaleSymbol[8];
141  char humid[32];
142  char dew_point[32];
143 
144  switch (tempScale)
145  {
146  case 0:
147  sprintf(tempScaleSymbol, "C");
148  break;
149  case 1:
150  sprintf(tempScaleSymbol, "F");
151  break;
152  case 2:
153  sprintf(tempScaleSymbol, "K");
154  break;
155 
156  default:
157  sprintf(tempScaleSymbol, "C");
158  break;
159  }
160 
161  sprintf(temp, "Temperature: %d %s", (int)c, tempScaleSymbol);
162  sprintf(humid, "Humidity: %d %%", (int)h);
163  sprintf(dew_point, "Dew Point: %d %s", (int)d, tempScaleSymbol);
164 
165  lcd.DisplayStringAt(0, LINE(6), (uint8_t *)temp, CENTER_MODE);
166  lcd.DisplayStringAt(0, LINE(7), (uint8_t *)humid, CENTER_MODE);
167  lcd.DisplayStringAt(0, LINE(8), (uint8_t *)dew_point, CENTER_MODE);
168  }
169 }
170 
176 {
177  float luminence = lightSensor.read();
178 
179  if (luminence < 0.3)
180  {
181  lcd.DisplayStringAt(0, LINE(12), (uint8_t *)"Godnat", CENTER_MODE);
182  }
183  else
184  {
185  lcd.DisplayStringAt(0, LINE(12), (uint8_t *)"Goddag", CENTER_MODE);
186  }
187 }
188 
189 Thread noiseThread;
190 bool noiseThreadStarted = false;
191 
197 {
198  while (noiseThreadStarted)
199  {
200  float noiseLevel = soundSensor.read();
201 
202  if (noiseLevel >= 0.5 && 1 == currentView)
203  {
204  lcd.DisplayStringAt(0, LINE(13), (uint8_t *)"Noise warning!", CENTER_MODE);
205  }
206  else
207  {
208  lcd.SetBackColor(LCD_BACKGROUND);
209  lcd.DisplayStringAt(0, LINE(13), (uint8_t *)" ", CENTER_MODE);
210  lcd.SetBackColor(LCD_TEXT_BACKGROUND);
211  }
212 
213  ThisThread::sleep_for(1000);
214  }
215 }
216 
222 {
223  char earth_quake[32];
224  sprintf(earth_quake, "Is Earthquake: %d", earthQuakeDetected());
225 
226  lcd.DisplayStringAt(0, LINE(10), (uint8_t *)earth_quake, CENTER_MODE);
227 }
228 
229 // Views
230 
233 
244 void drawButton(uint16_t xPos, u_int16_t yPos, uint8_t *Text, int dia = 10, int xOffset = 5, int yOffset = 7)
245 {
246  lcd.DrawCircle(xPos, yPos, dia);
247  lcd.SetBackColor(LCD_BACKGROUND);
248  lcd.DisplayStringAt((xPos - xOffset), (yPos - yOffset), Text, LEFT_MODE);
249  lcd.SetBackColor(LCD_TEXT_BACKGROUND);
250 }
251 
263 bool buttonHit(uint16_t xPos, uint16_t yPos, uint16_t cursor_x, uint16_t cursor_y, uint16_t hitBoxAera = 20)
264 {
265  int y_hitbox_min = yPos - hitBoxAera;
266  int y_hitbox_max = yPos + hitBoxAera;
267 
268  int x_hitbox_min = xPos - hitBoxAera;
269  int x_hitbox_max = xPos + hitBoxAera;
270 
271  if ((cursor_y >= y_hitbox_min && cursor_y <= y_hitbox_max) && (cursor_x >= x_hitbox_min && cursor_x <= x_hitbox_max))
272  {
273  return true;
274  }
275 
276  return false;
277 }
278 
284 {
285  char str_building[32];
286  char str_room[32];
287 
288  sprintf(str_building, "Building: %d", device_setup_building_no);
289  sprintf(str_room, "Room: %d", device_setup_room_no);
290 
291  lcd.DisplayStringAt(125, 75, (uint8_t *)str_building, LEFT_MODE);
292  lcd.DisplayStringAt(125, 150, (uint8_t *)str_room, LEFT_MODE);
293 
294  // Building adjustment
295  uint16_t building_incr_xPos = 300;
296  uint16_t building_incr_yPos = 80;
297  drawButton(building_incr_xPos, building_incr_yPos, (uint8_t *)"+");
298 
299  uint16_t building_decr_xPos = 350;
300  uint16_t building_decr_yPos = 80;
301  drawButton(building_decr_xPos, building_decr_yPos, (uint8_t *)"-");
302 
303  // Room adjustment
304  uint16_t room_incr_xPos = 300;
305  uint16_t room_incr_yPos = 155;
306  drawButton(room_incr_xPos, room_incr_yPos, (uint8_t *)"+");
307 
308  uint16_t room_decr_xPos = 350;
309  uint16_t room_decr_yPos = 155;
310  drawButton(room_decr_xPos, room_decr_yPos, (uint8_t *)"-");
311 
312  // Save button
313  uint16_t save_btn_xPos = 240;
314  uint16_t save_btn_yPos = 230;
315  drawButton(save_btn_xPos, save_btn_yPos, (uint8_t *)"Save", 32, 22);
316 
317  ts.GetState(&TS_State);
318  if (TS_State.touchDetected)
319  {
320  for (idx = 0; idx < TS_State.touchDetected; idx++)
321  {
322  x = TS_State.touchX[idx];
323  y = TS_State.touchY[idx];
324 
325  float btnPressWait = 0.3f;
326 
327  // Building adjustment
328  if (buttonHit(building_incr_xPos, building_incr_yPos, x, y))
329  {
331 
332  wait(btnPressWait);
333  }
334 
335  if (buttonHit(building_decr_xPos, building_decr_yPos, x, y))
336  {
338 
339  wait(btnPressWait);
340  }
341 
342  // Room adjustment
343  if (buttonHit(room_incr_xPos, room_incr_yPos, x, y))
344  {
346 
347  wait(btnPressWait);
348  }
349 
350  if (buttonHit(room_decr_xPos, room_incr_yPos, x, y))
351  {
353 
354  wait(btnPressWait);
355  }
356 
357  if (buttonHit(save_btn_xPos, save_btn_yPos, x, y))
358  {
361 
362  wait(0.5f);
363 
364  cleared = false;
365  }
366  }
367  }
368 }
369 
371 bool counterThreadStarted = false;
372 
378 {
379  while (counterThreadStarted)
380  {
381  counterTick();
382 
383  ThisThread::sleep_for(1000);
384  }
385 }
386 
391 void view1()
392 {
396 
398  {
400 
401  counterThreadStarted = true;
402  }
403 
404  if (!noiseThreadStarted)
405  {
406  noiseThread.start(noiseWarning);
407 
408  noiseThreadStarted = true;
409  }
410 }
411 
416 void view2()
417 {
418  char i2c_clock[32];
419  sprintf(i2c_clock, "I2C Clock: %d KHz", ((int)I2C_SPEED / 1000));
420  lcd.DisplayStringAt(0, LINE(3), (uint8_t *)i2c_clock, CENTER_MODE);
421 
422  if (BSP_SD_IsDetected())
423  {
424  lcd.DisplayStringAt(0, LINE(7), (uint8_t *)"SD Card detected", CENTER_MODE);
425  }
426  else
427  {
428  lcd.DisplayStringAt(0, LINE(7), (uint8_t *)"SD Card not detected", CENTER_MODE);
429  }
430 
431  lcd.DisplayStringAt(145, 150, (uint8_t *)"Temperature scale", LEFT_MODE);
432 
433  uint16_t tempBtnYpos = 190;
434  uint16_t tempBtnCelsiusPos = 170;
435  uint16_t tempBtnFahrenheitPos = 230;
436  uint16_t tempBtnKelvinPos = 290;
437 
438  drawButton(tempBtnCelsiusPos, tempBtnYpos, (uint8_t *)"C");
439  drawButton(tempBtnFahrenheitPos, tempBtnYpos, (uint8_t *)"F");
440  drawButton(tempBtnKelvinPos, tempBtnYpos, (uint8_t *)"K");
441 
442  ts.GetState(&TS_State);
443  if (TS_State.touchDetected)
444  {
445  for (idx = 0; idx < TS_State.touchDetected; idx++)
446  {
447  x = TS_State.touchX[idx];
448  y = TS_State.touchY[idx];
449 
450  // Building adjustment
451  if (buttonHit(tempBtnCelsiusPos, tempBtnYpos, x, y))
452  {
453  tempScale = 0;
454 
455  usbCom.printf("Temp scale switched to Celcius!");
456 
457  wait(0.5f);
458  }
459 
460  if (buttonHit(tempBtnFahrenheitPos, tempBtnYpos, x, y))
461  {
462  tempScale = 1;
463 
464  usbCom.printf("Temp scale switched to Fahrenheit!");
465 
466  wait(0.5f);
467  }
468 
469  if (buttonHit(tempBtnKelvinPos, tempBtnYpos, x, y))
470  {
471  tempScale = 2;
472 
473  usbCom.printf("Temp scale switched to Kelvin!");
474 
475  wait(0.5f);
476  }
477  }
478  }
479 }
480 
486 void setView(int viewNumber)
487 {
488  if (viewNumber != currentView)
489  {
490  usbCom.printf("[Toggle]: setView viewNumber %d!\n", viewNumber);
491  usbCom.printf("[Toggle]: setView currentView %d!\n", currentView);
492 
493  cleared = 0;
494 
495  clearDisplay();
496  }
497 
498  currentView = viewNumber;
499 
500  switch (viewNumber)
501  {
502  case 1:
503  view1();
504  break;
505  case 2:
506  view2();
507  break;
508 
509  default:
510  usbCom.printf("Unknown view number: %d\n", viewNumber);
511  break;
512  }
513 }
514 
520 {
521  wait(0.1);
522 
523  usbCom.printf("switchView toggled!\n");
524 
525  int viewNumber = currentView;
526 
527  if (currentView < viewCount)
528  {
529  viewNumber++;
530  }
531  else
532  {
533  viewNumber = 1;
534  }
535 
536  usbCom.printf("switchView viewNumber %d!\n", viewNumber);
537  usbCom.printf("switchView currentView %d!\n", currentView);
538 
539  setView(viewNumber);
540 }
541 
546 void boot()
547 {
548  led1 = 1;
549  lcd.Init();
550  buzzer = 0;
551 
552  //uint8_t *image = (uint8_t *)fallout;
553  //lcd.DrawBitmap(0, 0, image);
554 
555  lcd.DisplayStringAt(0, LINE(1), (uint8_t *)"Booting Hercules...", CENTER_MODE);
556  lcd.DisplayStringAt(0, LINE(4), (uint8_t *)"Please wait", CENTER_MODE);
557 
558  if (BSP_SD_IsDetected())
559  {
560  BSP_SD_Init();
561  lcd.DisplayStringAt(0, LINE(6), (uint8_t *)"SD Card detected", CENTER_MODE);
562  }
563  else
564  {
565  lcd.DisplayStringAt(0, LINE(6), (uint8_t *)"SD Card not detected", CENTER_MODE);
566  }
567 
568  wait(1.0f);
569 
570  clearDisplay();
571 }
572 
578 {
579  while (true)
580  {
581  if (!buildingNumber && !roomNumber)
582  {
583  deviceSetup();
584  }
585  else
586  {
588  }
589 
590  ts.GetState(&TS_State);
591  if (buildingNumber && roomNumber && TS_State.touchDetected)
592  {
593  for (idx = 0; idx < TS_State.touchDetected; idx++)
594  {
595  x = TS_State.touchX[idx];
596  y = TS_State.touchY[idx];
597 
598  int y_hitbox_min = 240 - 50;
599  int y_hitbox_max = 240 + 50;
600 
601  int x_hitbox_min = 410 - 50;
602  int x_hitbox_max = 410 + 50;
603 
604  if ((y >= y_hitbox_min && y <= y_hitbox_max) && (x >= x_hitbox_min && x <= x_hitbox_max))
605  {
606  switchView();
607  }
608  }
609  }
610  else
611  {
612  if (!cleared)
613  {
614  clearDisplay();
615 
616  char displayView[32];
617  sprintf(displayView, "View: %d", currentView);
618 
619  lcd.DrawHLine(10, 10, 460);
620  lcd.SetFont(&Font8);
621 
622  lcd.SetBackColor(LCD_BACKGROUND);
623  lcd.DisplayStringAt(10, 12, (uint8_t *)"Hercules v1.1", LEFT_MODE);
624  lcd.DrawVLine(80, 10, 11);
625 
626  if (buildingNumber && roomNumber)
627  {
628  char building[32];
629  char room[32];
630 
631  sprintf(building, "Building: %d", buildingNumber);
632  sprintf(room, "Room: %d", roomNumber);
633 
634  lcd.DisplayStringAt(85, 12, (uint8_t *)building, LEFT_MODE);
635  lcd.DisplayStringAt(150, 12, (uint8_t *)room, LEFT_MODE);
636  }
637 
638  lcd.SetBackColor(LCD_TEXT_BACKGROUND);
639 
640  lcd.DrawHLine(10, 20, 460);
641  lcd.SetFont(&Font16);
642 
643  if (buildingNumber && roomNumber)
644  {
645  lcd.DisplayStringAt(10, 240, (uint8_t *)displayView, LEFT_MODE);
646  lcd.DisplayStringAt(410, 240, (uint8_t *)"Next", LEFT_MODE);
647  }
648 
649  cleared = 1;
650  }
651  }
652  }
653 }
654 
655 Thread guiThread;
656 
662 int main()
663 {
664  boot();
665 
666  // The data cache is disabled to avoid screen flickering.
667  SCB_CleanDCache();
668  SCB_DisableDCache();
669 
670  wait(0.25);
671 
672  guiThread.start(gui_thread);
673 }
TS_DISCO_F746NG ts
Definition: main.cpp:18
LCD_DISCO_F746NG lcd
Definition: main.cpp:16
int counter_max
Definition: main.cpp:49
void displayLightStatus()
Says "godnat" when dark, "goddag" when light.
Definition: main.cpp:175
AnalogIn lightSensor(A2)
#define LCD_TEXT_BACKGROUND
Definition: display.h:7
Thread guiThread
Definition: main.cpp:655
bool counterThreadStarted
Definition: main.cpp:371
uint8_t cleared
Definition: main.cpp:45
void displayEarthQuakeStatus()
Displays current earthquake status.
Definition: main.cpp:221
DigitalOut led1(LED1)
void switchView()
Switches the current view.
Definition: main.cpp:519
Thread noiseThread
Definition: main.cpp:189
bool buttonHit(uint16_t xPos, uint16_t yPos, uint16_t cursor_x, uint16_t cursor_y, uint16_t hitBoxAera=20)
Checks if a button has been hit.
Definition: main.cpp:263
void drawButton(uint16_t xPos, u_int16_t yPos, uint8_t *Text, int dia=10, int xOffset=5, int yOffset=7)
Draw a round button on screen.
Definition: main.cpp:244
AnalogIn soundSensor(A3)
void displayCurrentHT()
Displays temperature & humidity (humidity)
Definition: main.cpp:127
int main()
Application entry point.
Definition: main.cpp:662
AnalogIn vibrationSensor(A1)
Serial usbCom(USBTX, USBRX)
void setView(int viewNumber)
Set the View object.
Definition: main.cpp:486
int currentView
Definition: main.cpp:34
void noiseWarning()
Displays a warning when the noise is too much.
Definition: main.cpp:196
void gui_thread()
Gui Thread.
Definition: main.cpp:577
void view2()
View 2 logic.
Definition: main.cpp:416
DHT dhtSensor(A0, SEN51035P)
void clearDisplay()
Clears the main display & sets default colors.
Definition: main.cpp:86
TS_StateTypeDef TS_State
Definition: main.cpp:40
int roomNumber
Definition: main.cpp:52
int tempScale
Definition: main.cpp:37
void counterTick()
Increases the current count or resets when counter_max is hit.
Definition: main.cpp:59
int device_setup_building_no
Definition: main.cpp:231
int earthQuakeDetected()
Detects earth quakes. Sets the red led to ON/OFF.
Definition: main.cpp:109
#define LCD_BACKGROUND
LCD color.
Definition: display.h:6
void deviceSetup()
Initial device setup view.
Definition: main.cpp:283
uint16_t x
Definition: main.cpp:41
bool noiseThreadStarted
Definition: main.cpp:190
void boot()
Setup for app.
Definition: main.cpp:546
#define LCD_TEXT_COLOR
Definition: display.h:8
Thread counterThread
Definition: main.cpp:370
uint16_t y
Definition: main.cpp:41
int counter_current
Definition: main.cpp:50
DigitalOut buzzer(D4)
uint8_t status
Definition: main.cpp:43
DigitalOut led2(D2)
uint8_t text[30]
Definition: main.cpp:42
int device_setup_room_no
Definition: main.cpp:232
int viewCount
Definition: main.cpp:35
int buildingNumber
Definition: main.cpp:53
void counter_thread()
Counter task.
Definition: main.cpp:377
uint8_t prev_nb_touches
Definition: main.cpp:46
uint8_t idx
Definition: main.cpp:44
void view1()
View 1 logic.
Definition: main.cpp:391