Test

Dependencies:   mbed Adafruit_GFX DS1307

Committer:
VinPer
Date:
Sat Jun 01 14:47:54 2019 +0000
Revision:
0:4ee8e6f5f993
bla

Who changed what in which revision?

UserRevisionLine numberNew contents of line
VinPer 0:4ee8e6f5f993 1 #include "mbed.h"
VinPer 0:4ee8e6f5f993 2 #include "Adafruit_SSD1306.h"
VinPer 0:4ee8e6f5f993 3 #include <string>
VinPer 0:4ee8e6f5f993 4 #include <sstream>
VinPer 0:4ee8e6f5f993 5
VinPer 0:4ee8e6f5f993 6 void Rx_interrupt();
VinPer 0:4ee8e6f5f993 7 void writeStringToOLED(string str, int x, int y);
VinPer 0:4ee8e6f5f993 8 void showStatus();
VinPer 0:4ee8e6f5f993 9 void toggleLED();
VinPer 0:4ee8e6f5f993 10 void waterPlant();
VinPer 0:4ee8e6f5f993 11 void waterCritical();
VinPer 0:4ee8e6f5f993 12
VinPer 0:4ee8e6f5f993 13 void drawSmile();
VinPer 0:4ee8e6f5f993 14 void drawIdle();
VinPer 0:4ee8e6f5f993 15 void drawSleep();
VinPer 0:4ee8e6f5f993 16 void drawDead();
VinPer 0:4ee8e6f5f993 17
VinPer 0:4ee8e6f5f993 18 volatile bool sleepCycle;
VinPer 0:4ee8e6f5f993 19
VinPer 0:4ee8e6f5f993 20 /*
VinPer 0:4ee8e6f5f993 21 OLED
VinPer 0:4ee8e6f5f993 22 P5 -> MOSI
VinPer 0:4ee8e6f5f993 23 P6 -> aberto
VinPer 0:4ee8e6f5f993 24 P7 -> CLK
VinPer 0:4ee8e6f5f993 25 Pinos variáveis
VinPer 0:4ee8e6f5f993 26 P8 -> RES
VinPer 0:4ee8e6f5f993 27 P9 -> DC
VinPer 0:4ee8e6f5f993 28 P10 -> CS
VinPer 0:4ee8e6f5f993 29
VinPer 0:4ee8e6f5f993 30 Configuração SPI entra com (MOSI, MISO, CLK)
VinPer 0:4ee8e6f5f993 31 Configuração OLED entra com (SPI, DC, RES, CS, altura, largura)
VinPer 0:4ee8e6f5f993 32 */
VinPer 0:4ee8e6f5f993 33 SPI spi(p5, p6, p7);
VinPer 0:4ee8e6f5f993 34 Adafruit_SSD1306_Spi spiOLED(spi, p9, p8, p10, 32, 128);
VinPer 0:4ee8e6f5f993 35
VinPer 0:4ee8e6f5f993 36 /*
VinPer 0:4ee8e6f5f993 37 BLUETOOTH
VinPer 0:4ee8e6f5f993 38 P13 -> TX
VinPer 0:4ee8e6f5f993 39 P14 -> RX
VinPer 0:4ee8e6f5f993 40
VinPer 0:4ee8e6f5f993 41 Configuração serial entra com (RX, TX)
VinPer 0:4ee8e6f5f993 42 */
VinPer 0:4ee8e6f5f993 43
VinPer 0:4ee8e6f5f993 44
VinPer 0:4ee8e6f5f993 45 Serial hc(p14, p13);
VinPer 0:4ee8e6f5f993 46
VinPer 0:4ee8e6f5f993 47 /*
VinPer 0:4ee8e6f5f993 48 Componentes que utilizam leitura análogica:
VinPer 0:4ee8e6f5f993 49 P15 a P20
VinPer 0:4ee8e6f5f993 50 */
VinPer 0:4ee8e6f5f993 51 AnalogIn ldr(p15);
VinPer 0:4ee8e6f5f993 52 AnalogIn hygroEarth(p16);
VinPer 0:4ee8e6f5f993 53 AnalogIn hygroWater(p17);
VinPer 0:4ee8e6f5f993 54
VinPer 0:4ee8e6f5f993 55 /*
VinPer 0:4ee8e6f5f993 56 Componentes que utilizam leitura digital:
VinPer 0:4ee8e6f5f993 57 Qualquer pino livre (P5 a P30)
VinPer 0:4ee8e6f5f993 58 */
VinPer 0:4ee8e6f5f993 59 DigitalIn pres(p30);
VinPer 0:4ee8e6f5f993 60
VinPer 0:4ee8e6f5f993 61 volatile bool ledStatus;
VinPer 0:4ee8e6f5f993 62 volatile float waterLimit;
VinPer 0:4ee8e6f5f993 63 volatile time_t seconds;
VinPer 0:4ee8e6f5f993 64
VinPer 0:4ee8e6f5f993 65 int main()
VinPer 0:4ee8e6f5f993 66 {
VinPer 0:4ee8e6f5f993 67 set_time(0);
VinPer 0:4ee8e6f5f993 68 seconds = time(NULL);
VinPer 0:4ee8e6f5f993 69 // Resetar display
VinPer 0:4ee8e6f5f993 70 spiOLED.clearDisplay();
VinPer 0:4ee8e6f5f993 71 drawSmile();
VinPer 0:4ee8e6f5f993 72 spiOLED.display();
VinPer 0:4ee8e6f5f993 73 wait(10);
VinPer 0:4ee8e6f5f993 74 drawIdle();
VinPer 0:4ee8e6f5f993 75
VinPer 0:4ee8e6f5f993 76 ledStatus = false;
VinPer 0:4ee8e6f5f993 77 sleepCycle = false;
VinPer 0:4ee8e6f5f993 78
VinPer 0:4ee8e6f5f993 79 int tsEarth = 0; //
VinPer 0:4ee8e6f5f993 80 int tsLight = 0; //
VinPer 0:4ee8e6f5f993 81 int tsPres = 0; //
VinPer 0:4ee8e6f5f993 82
VinPer 0:4ee8e6f5f993 83 int delayEarth = 3600; //
VinPer 0:4ee8e6f5f993 84 int delayLight; //
VinPer 0:4ee8e6f5f993 85 int delayPres = 7200; //
VinPer 0:4ee8e6f5f993 86
VinPer 0:4ee8e6f5f993 87 waterLimit = 1;
VinPer 0:4ee8e6f5f993 88 float lightLimit = 1; //
VinPer 0:4ee8e6f5f993 89 float earthLimit = 1; //
VinPer 0:4ee8e6f5f993 90
VinPer 0:4ee8e6f5f993 91 bool turnOnLED;
VinPer 0:4ee8e6f5f993 92 bool turnOffLED;
VinPer 0:4ee8e6f5f993 93
VinPer 0:4ee8e6f5f993 94 while(1){
VinPer 0:4ee8e6f5f993 95 seconds = time(NULL);
VinPer 0:4ee8e6f5f993 96
VinPer 0:4ee8e6f5f993 97 /*
VinPer 0:4ee8e6f5f993 98 HIGRÔMETRO TERRA
VinPer 0:4ee8e6f5f993 99 - Rega a planta quando o nível de umidade detectado for adequado
VinPer 0:4ee8e6f5f993 100 - Não rega se não tiver passado um determinado tempo desde a ultima vez
VinPer 0:4ee8e6f5f993 101
VinPer 0:4ee8e6f5f993 102 Condição 1: Valor lido no higrômetro da terra maior (mais seco) que o limite
VinPer 0:4ee8e6f5f993 103 Condição 2: Tempo desde a ultima vez que foi regado maior que o delay mínimo
VinPer 0:4ee8e6f5f993 104 */
VinPer 0:4ee8e6f5f993 105 if (hygroEarth.read() > earthLimit && seconds - tsEarth > delayEarth) {
VinPer 0:4ee8e6f5f993 106 tsEarth = seconds;
VinPer 0:4ee8e6f5f993 107 waterPlant();
VinPer 0:4ee8e6f5f993 108 }
VinPer 0:4ee8e6f5f993 109
VinPer 0:4ee8e6f5f993 110 /*
VinPer 0:4ee8e6f5f993 111 SENSOR LDR E FITA DE LED
VinPer 0:4ee8e6f5f993 112 - Liga/desliga a fita de LED dependendo do nível de luz
VinPer 0:4ee8e6f5f993 113 (acrescentar: do horário do dia)
VinPer 0:4ee8e6f5f993 114
VinPer 0:4ee8e6f5f993 115 Condição 1: Valor lido no LDR inferior a luz necessária
VinPer 0:4ee8e6f5f993 116 Condição 2: LED está desligado
VinPer 0:4ee8e6f5f993 117 Condição 3 (acrescentar): horário atual não ser noite
VinPer 0:4ee8e6f5f993 118 */
VinPer 0:4ee8e6f5f993 119 turnOnLED = ldr.read() < lightLimit && !ledStatus;
VinPer 0:4ee8e6f5f993 120 // Mesmas condições, mas inversas para desligar
VinPer 0:4ee8e6f5f993 121 turnOffLED = ldr.read() > lightLimit && ledStatus;
VinPer 0:4ee8e6f5f993 122 if (turnOnLED || turnOffLED) {
VinPer 0:4ee8e6f5f993 123 toggleLED();
VinPer 0:4ee8e6f5f993 124 }
VinPer 0:4ee8e6f5f993 125
VinPer 0:4ee8e6f5f993 126 /*
VinPer 0:4ee8e6f5f993 127 SENSOR PRESENÇA
VinPer 0:4ee8e6f5f993 128 - Desenha uma carinha feliz quando detecta presença de alguém ^u^
VinPer 0:4ee8e6f5f993 129
VinPer 0:4ee8e6f5f993 130 Condição 1: Valor lido no sensor de presença é 1
VinPer 0:4ee8e6f5f993 131 Condição 2: Tempo desde a ultima vez que foi ativado maior que o delay mínimo
VinPer 0:4ee8e6f5f993 132 */
VinPer 0:4ee8e6f5f993 133 if (pres.read() && seconds - tsPres > delayPres) {
VinPer 0:4ee8e6f5f993 134 tsPres = seconds;
VinPer 0:4ee8e6f5f993 135 drawSmile();
VinPer 0:4ee8e6f5f993 136 wait(15);
VinPer 0:4ee8e6f5f993 137 }
VinPer 0:4ee8e6f5f993 138
VinPer 0:4ee8e6f5f993 139 /*
VinPer 0:4ee8e6f5f993 140 HIGRÔMETRO ÁGUA
VinPer 0:4ee8e6f5f993 141 - Interrompe o programa no caso de não ter água no tanque
VinPer 0:4ee8e6f5f993 142
VinPer 0:4ee8e6f5f993 143 Condição 1: Valor lido no higrômetro da água maior (mais seco) que o limite
VinPer 0:4ee8e6f5f993 144 */
VinPer 0:4ee8e6f5f993 145 if (hygroWater.read() > waterLimit) {
VinPer 0:4ee8e6f5f993 146 waterCritical();
VinPer 0:4ee8e6f5f993 147 }
VinPer 0:4ee8e6f5f993 148
VinPer 0:4ee8e6f5f993 149 /*
VinPer 0:4ee8e6f5f993 150 DORMIR
VinPer 0:4ee8e6f5f993 151 - O vaso dorme quando o horário for de noite.
VinPer 0:4ee8e6f5f993 152
VinPer 0:4ee8e6f5f993 153 Condição 1: ??? horas noturnas
VinPer 0:4ee8e6f5f993 154 */
VinPer 0:4ee8e6f5f993 155
VinPer 0:4ee8e6f5f993 156 // ...
VinPer 0:4ee8e6f5f993 157 if (true) {
VinPer 0:4ee8e6f5f993 158 drawSleep();
VinPer 0:4ee8e6f5f993 159 }
VinPer 0:4ee8e6f5f993 160
VinPer 0:4ee8e6f5f993 161 wait(1);
VinPer 0:4ee8e6f5f993 162 }
VinPer 0:4ee8e6f5f993 163 }
VinPer 0:4ee8e6f5f993 164
VinPer 0:4ee8e6f5f993 165 // Receber comandos manuais por bluetooth
VinPer 0:4ee8e6f5f993 166 void Rx_interrupt() {
VinPer 0:4ee8e6f5f993 167 char c;
VinPer 0:4ee8e6f5f993 168 c = hc.getc();
VinPer 0:4ee8e6f5f993 169 switch(c){
VinPer 0:4ee8e6f5f993 170 case 'S':
VinPer 0:4ee8e6f5f993 171 showStatus();
VinPer 0:4ee8e6f5f993 172 break;
VinPer 0:4ee8e6f5f993 173 case 'A':
VinPer 0:4ee8e6f5f993 174 waterPlant();
VinPer 0:4ee8e6f5f993 175 break;
VinPer 0:4ee8e6f5f993 176 case 'L':
VinPer 0:4ee8e6f5f993 177 toggleLED();
VinPer 0:4ee8e6f5f993 178 break;
VinPer 0:4ee8e6f5f993 179 default:
VinPer 0:4ee8e6f5f993 180 break;
VinPer 0:4ee8e6f5f993 181 }
VinPer 0:4ee8e6f5f993 182 }
VinPer 0:4ee8e6f5f993 183
VinPer 0:4ee8e6f5f993 184 void writeStringToOLED(string str, int x, int y) {
VinPer 0:4ee8e6f5f993 185 spiOLED.setTextCursor(x, y);
VinPer 0:4ee8e6f5f993 186 spiOLED.fillRect(x, y, 128, 8, 0);
VinPer 0:4ee8e6f5f993 187 for(int i = 0; i < str.length(); i++) {
VinPer 0:4ee8e6f5f993 188 spiOLED.writeChar(str[i]);
VinPer 0:4ee8e6f5f993 189 }
VinPer 0:4ee8e6f5f993 190 spiOLED.display();
VinPer 0:4ee8e6f5f993 191 }
VinPer 0:4ee8e6f5f993 192
VinPer 0:4ee8e6f5f993 193 // Mostra todas as leituras atuais
VinPer 0:4ee8e6f5f993 194 void showStatus() {
VinPer 0:4ee8e6f5f993 195 hc.printf("Presença: %d\nLDR: %.5f\nHigrometro Terra: %.5f\nHigrometro Agua: %.5f",
VinPer 0:4ee8e6f5f993 196 pres.read(),
VinPer 0:4ee8e6f5f993 197 ldr.read(),
VinPer 0:4ee8e6f5f993 198 hygroEarth.read(),
VinPer 0:4ee8e6f5f993 199 hygroWater.read());
VinPer 0:4ee8e6f5f993 200 }
VinPer 0:4ee8e6f5f993 201
VinPer 0:4ee8e6f5f993 202 // Rega a planta a força, desde que tenha água no reservatório
VinPer 0:4ee8e6f5f993 203 void waterPlant() {
VinPer 0:4ee8e6f5f993 204 if(hygroWater.read() > waterLimit) waterCritical();
VinPer 0:4ee8e6f5f993 205 // ...
VinPer 0:4ee8e6f5f993 206 }
VinPer 0:4ee8e6f5f993 207
VinPer 0:4ee8e6f5f993 208 // Interrompe o funcionamento do vaso até que seja alimentado com água
VinPer 0:4ee8e6f5f993 209 void waterCritical() {
VinPer 0:4ee8e6f5f993 210 drawDead();
VinPer 0:4ee8e6f5f993 211
VinPer 0:4ee8e6f5f993 212 while(hygroWater.read() > waterLimit) {
VinPer 0:4ee8e6f5f993 213 // whatever?!
VinPer 0:4ee8e6f5f993 214
VinPer 0:4ee8e6f5f993 215 wait(1);
VinPer 0:4ee8e6f5f993 216 }
VinPer 0:4ee8e6f5f993 217
VinPer 0:4ee8e6f5f993 218 drawIdle();
VinPer 0:4ee8e6f5f993 219 }
VinPer 0:4ee8e6f5f993 220
VinPer 0:4ee8e6f5f993 221 // Liga/desliga os LEDs
VinPer 0:4ee8e6f5f993 222 void toggleLED() {
VinPer 0:4ee8e6f5f993 223 ledStatus = !ledStatus;
VinPer 0:4ee8e6f5f993 224 // ...
VinPer 0:4ee8e6f5f993 225 }
VinPer 0:4ee8e6f5f993 226
VinPer 0:4ee8e6f5f993 227 // Desenha uma carinha feliz ^u^
VinPer 0:4ee8e6f5f993 228 void drawSmile() {
VinPer 0:4ee8e6f5f993 229 spiOLED.drawCircle(12, 20, 9, 1);
VinPer 0:4ee8e6f5f993 230 spiOLED.fillRect(0, 5, 22, 15, 0);
VinPer 0:4ee8e6f5f993 231 spiOLED.fillTriangle(2, 15, 10, 15, 6, 7, 1);
VinPer 0:4ee8e6f5f993 232 spiOLED.fillTriangle(3, 15, 9, 15, 6, 8, 0);
VinPer 0:4ee8e6f5f993 233 spiOLED.fillTriangle(14, 15, 22, 15, 18, 7, 1);
VinPer 0:4ee8e6f5f993 234 spiOLED.fillTriangle(15, 15, 21, 15, 18, 8, 0);
VinPer 0:4ee8e6f5f993 235 spiOLED.setTextSize(2);
VinPer 0:4ee8e6f5f993 236 writeStringToOLED("Hello!", 30, 10);
VinPer 0:4ee8e6f5f993 237 }
VinPer 0:4ee8e6f5f993 238
VinPer 0:4ee8e6f5f993 239 void drawIdle() {
VinPer 0:4ee8e6f5f993 240 spiOLED.drawCircle(12, 20, 9, 1);
VinPer 0:4ee8e6f5f993 241 spiOLED.fillRect(0, 5, 22, 15, 0);
VinPer 0:4ee8e6f5f993 242 spiOLED.fillRect(7, 6, 2, 10, 1);
VinPer 0:4ee8e6f5f993 243 spiOLED.fillRect(16, 6, 2, 10, 1);
VinPer 0:4ee8e6f5f993 244 spiOLED.setTextSize(2);
VinPer 0:4ee8e6f5f993 245 writeStringToOLED("All ok!", 40, 10);
VinPer 0:4ee8e6f5f993 246 }
VinPer 0:4ee8e6f5f993 247
VinPer 0:4ee8e6f5f993 248 void drawSleep() {
VinPer 0:4ee8e6f5f993 249 int y = 1;
VinPer 0:4ee8e6f5f993 250 while(sleepCycle) {
VinPer 0:4ee8e6f5f993 251 spiOLED.clearDisplay();
VinPer 0:4ee8e6f5f993 252 spiOLED.drawCircle(10, 23, 3, 1);
VinPer 0:4ee8e6f5f993 253 spiOLED.fillRect(2, 12, 8, 2, 1);
VinPer 0:4ee8e6f5f993 254 spiOLED.fillRect(15, 12, 8, 2, 1);
VinPer 0:4ee8e6f5f993 255 spiOLED.setTextSize(1);
VinPer 0:4ee8e6f5f993 256 writeStringToOLED("z", 35, 16 + y * 3);
VinPer 0:4ee8e6f5f993 257 spiOLED.setTextSize(2);
VinPer 0:4ee8e6f5f993 258 writeStringToOLED("z", 45, 11 - y * 3);
VinPer 0:4ee8e6f5f993 259 spiOLED.setTextSize(3);
VinPer 0:4ee8e6f5f993 260 writeStringToOLED("z", 65, 6 + y * 3);
VinPer 0:4ee8e6f5f993 261 spiOLED.setTextSize(4);
VinPer 0:4ee8e6f5f993 262 writeStringToOLED("z", 90, 1 - y * 3);
VinPer 0:4ee8e6f5f993 263 wait(1);
VinPer 0:4ee8e6f5f993 264 y = y * -1;
VinPer 0:4ee8e6f5f993 265
VinPer 0:4ee8e6f5f993 266 // ...
VinPer 0:4ee8e6f5f993 267 if (seconds > 86400) sleepCycle = false;
VinPer 0:4ee8e6f5f993 268 }
VinPer 0:4ee8e6f5f993 269 }
VinPer 0:4ee8e6f5f993 270
VinPer 0:4ee8e6f5f993 271 void drawDead() {
VinPer 0:4ee8e6f5f993 272 spiOLED.drawCircle(13, 27, 7, 1);
VinPer 0:4ee8e6f5f993 273 spiOLED.fillRect(0, 28, 22, 15, 0);
VinPer 0:4ee8e6f5f993 274 spiOLED.drawLine(2, 15, 10, 7, 1);
VinPer 0:4ee8e6f5f993 275 spiOLED.drawLine(2, 7, 10, 15, 1);
VinPer 0:4ee8e6f5f993 276 spiOLED.drawLine(16, 15, 24, 7, 1);
VinPer 0:4ee8e6f5f993 277 spiOLED.drawLine(16, 7, 24, 15, 1);
VinPer 0:4ee8e6f5f993 278 spiOLED.setTextSize(2);
VinPer 0:4ee8e6f5f993 279 writeStringToOLED("Help!", 50, 6);
VinPer 0:4ee8e6f5f993 280 spiOLED.setTextSize(1);
VinPer 0:4ee8e6f5f993 281 writeStringToOLED("Need water!!", 50, 22);
VinPer 0:4ee8e6f5f993 282 }