///////////////////////////////////////// // HXbot HXlcd firmware / // EoF 2016 EoF@itphx.ru / ///////////////////////////////////////// #include #include #include // Core graphics library #include // Hardware-specific library #include #include "HXlcd2.h" // DEBUG #define DEBUG 1 // DEFINE #define SLAVE_ADDRESS 0x06 #define XOR_SEQ 0xFF #define EXT_COM 0xAA #define R_LED 10 #define G_LED 9 #define B_LED 11 #define L_BTN A3 #define C_BTN A2 #define R_BTN A1 //clk 4, din 5, dc 6, cs 7, rst 8 #define TFT_BL 3 #define TFT_SCLK 4 #define TFT_MOSI 5 #define TFT_DC 6 #define TFT_CS 7 #define TFT_RST 8 // Sensors #define LIGHT A6 #define LOUD A7 #define TEMP A0 #define BUZZ 13 #define FREE 12 #define LED_PIN 13 #define DELAY1 2000 #define DELAY2 500 // COMMANDS // Util #define COM_PING 0x01 #define COM_GET_TEMP 0x02 // Response #define OK_RSP 0x00 #define NO_RSP 0xFF #define ERR_RSP 0x01 #define BLK_RSP 0x02 #define CSE_RSP 0x03 #define IOE_RSP 0x04 #define TMO_RSP 0x05 // VAR DHT11 dht(TEMP); Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); // эту константу (typVbg) необходимо откалибровать индивидуально const float typVbg = 1.08; // 1.0 -- 1.2 byte autoresponse = 0; byte cmd = 0; byte flg = 0; byte ext = 0; int temp, hum; float p = 3.1415926; float vcc; bool l_pressed = false, c_pressed = false, r_pressed = false; bool menu_drawed = false; byte screen = 0, line = 1; unsigned long t; void setup() { if (DEBUG) { Serial.begin(9600); Serial.println("GO!"); } // Initialize i2c as slave Wire.begin(SLAVE_ADDRESS); // Define callbacks for i2c communication Wire.onReceive(receiveData); Wire.onRequest(answer); // put your setup code here, to run once: pinMode(LED_PIN, OUTPUT); pinMode(R_LED, OUTPUT); pinMode(G_LED, OUTPUT); pinMode(B_LED, OUTPUT); pinMode(TFT_BL, OUTPUT); pinMode(L_BTN, INPUT_PULLUP); pinMode(C_BTN, INPUT_PULLUP); pinMode(R_BTN, INPUT_PULLUP); pinMode(LIGHT, INPUT); pinMode(LOUD, INPUT); pinMode(FREE, INPUT); pinMode(BUZZ, OUTPUT); randomSeed(millis()); analogReference(DEFAULT); // Use this initializer if you're using a 1.8" TFT tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab tft.fillScreen(ST7735_BLACK); tft.drawRect(0, 0, 128, 160, ST7735_GREEN); tft.drawRect(1, 1, 126, 158, ST7735_WHITE); drawL(); drawC(); drawR(); analogWrite(TFT_BL, 255); dht.begin(); } void loop() { if (digitalRead(FREE) == HIGH) { analogWrite(G_LED, 128); } else { analogWrite(G_LED, 0); } // if (DEBUG) { // Serial.println(r_pressed); // Serial.println(c_pressed); // Serial.println(l_pressed); // } readButtons(); drawMenu(); //displayALL(); } void drawMenu() { if (millis() - t < BTN_TIMEOUT) return; if (screen == 0) { if (l_pressed) { line++; if (line > SCR1_MAX) line = 1; drawPointer(); t = millis(); } if (r_pressed) { line--; if (line < 1) line = SCR1_MAX; drawPointer(); t = millis(); } if (! menu_drawed) { tft.setTextSize(1); tft.setCursor(52, 8); tft.print("MAIN"); tft.setTextSize(1); tft.setCursor(20, 20); tft.print("HXbot"); tft.setCursor(20, 30); tft.print("REflex"); tft.setCursor(20, 40); tft.print("HXpower"); tft.setCursor(20, 50); tft.print("HXlcd"); tft.setCursor(20, 60); tft.print("HXcamera"); drawPointer(); menu_drawed = true; } if (c_pressed) { screen = line; line = 0; clearMenu(); t = millis(); return; } } if (screen == 1) { if (! menu_drawed) { tft.setTextSize(1); tft.setCursor(49, 8); tft.print("HXbot"); tft.setTextSize(1); tft.setCursor(52, 130); tft.print("back"); drawPointer(); menu_drawed = true; } if (c_pressed) { screen = 0; line = 1; clearMenu(); t = millis(); return; } } if (screen == 2) { if (! menu_drawed) { tft.setTextSize(1); tft.setCursor(49, 8); tft.print("REflex"); tft.setTextSize(1); tft.setCursor(52, 130); tft.print("back"); drawPointer(); menu_drawed = true; } if (c_pressed) { screen = 0; line = 1; clearMenu(); t = millis(); return; } } if (screen == 3) { if (! menu_drawed) { tft.setTextSize(1); tft.setCursor(49, 8); tft.print("HXpower"); tft.setTextSize(1); tft.setCursor(52, 130); tft.print("back"); drawPointer(); menu_drawed = true; } if (c_pressed) { screen = 0; line = 1; clearMenu(); t = millis(); return; } } if (screen == 4) { if (! menu_drawed) { tft.setTextSize(1); tft.setCursor(49, 8); tft.print("HXlcd"); tft.setTextSize(1); tft.setCursor(52, 130); tft.print("back"); drawPointer(); menu_drawed = true; } if (c_pressed) { screen = 0; line = 1; clearMenu(); t = millis(); return; } } if (screen == 5) { if (! menu_drawed) { tft.setTextSize(1); tft.setCursor(49, 8); tft.print("HXcamera"); tft.setTextSize(1); tft.setCursor(52, 130); tft.print("back"); drawPointer(); menu_drawed = true; } if (c_pressed) { screen = 0; line = 1; clearMenu(); t = millis(); return; } } } void clearMenu() { tft.fillRect(2, 2, 123, 140, BLACK); menu_drawed = false; } void drawPointer() { byte x1, y1, x2, y2, x3, y3; if (line != 0) { x1 = 10; y1 = 11 + line * 10; x2 = 10; y2 = 15 + line * 10; x3 = 15; y3 = 13 + line * 10; } else { x1 = 42; y1 = 131; x2 = 42; y2 = 135; x3 = 47; y3 = 133; } tft.fillRect(10, 20, 6, 100, BLACK); tft.fillTriangle(x1, y1, x2, y2, x3, y3, WHITE); } void displayALL() { // Vcc vcc = readvcc(); tft.setCursor(10, 10); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print("Vcc="); if (vcc < 4.8 || vcc > 5.2) tft.setTextColor(ST7735_RED, ST7735_BLACK); else tft.setTextColor(ST7735_GREEN, ST7735_BLACK); tft.print(vcc); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print(" V "); // Light tft.setCursor(10, 20); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print("Lightness="); tft.setTextColor(ST7735_YELLOW, ST7735_BLACK); tft.print(analogRead(LIGHT)); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print(" UE "); // Loud tft.setCursor(10, 30); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print("Loud="); tft.setTextColor(ST7735_MAGENTA, ST7735_BLACK); tft.print(analogRead(LOUD)); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print(" UE "); // TH int result; result = dht.read(); tft.setCursor(10, 40); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print("Temp="); tft.setTextColor(ST7735_CYAN, ST7735_BLACK); if (result == DHT_OK) tft.print(dht.getTemperatureC()); else tft.print("ERR"); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print(" C "); tft.setCursor(10, 50); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print("Hum="); tft.setTextColor(ST7735_BLUE, ST7735_BLACK); if (result == DHT_OK) tft.print(dht.getHumidity()); else tft.print("ERR"); tft.setTextColor(ST7735_WHITE, ST7735_BLACK); tft.print(" % "); } void readButtons() { if ((digitalRead(L_BTN) == LOW) && ! l_pressed) { l_pressed = true; drawL(); } else { if ((digitalRead(L_BTN) == HIGH) && l_pressed) { l_pressed = false; drawL(); } } if ((digitalRead(C_BTN) == LOW) && ! c_pressed) { c_pressed = true; drawC(); } else { if ((digitalRead(C_BTN) == HIGH) && c_pressed) { c_pressed = false; drawC(); } } if ((digitalRead(R_BTN) == LOW) && ! r_pressed) { r_pressed = true; drawR(); } else { if ((digitalRead(R_BTN) == HIGH) && r_pressed) { r_pressed = false; drawR(); } } } void drawL() { tft.fillRoundRect(4, 145, 37, 12, 3, YELLOW); if (! l_pressed) { tft.drawRoundRect(4, 145, 37, 12, 3, LYELLOW); tft.drawLine(6, 156, 38, 156, DYELLOW); tft.drawLine(40, 147, 40, 154, DYELLOW); tft.drawPixel(5, 155, DYELLOW); tft.drawPixel(39, 155, DYELLOW); tft.fillTriangle(15, 147, 29, 147, 22, 154, GRAY); tft.drawTriangle(15, 147, 29, 147, 22, 154, DGRAY); } else { tft.drawRoundRect(4, 145, 37, 12, 3, DYELLOW); tft.drawLine(6, 156, 38, 156, LYELLOW); tft.drawLine(40, 147, 40, 154, LYELLOW); tft.drawPixel(5, 155, LYELLOW); tft.drawPixel(39, 155, LYELLOW); tft.fillTriangle(15, 147, 29, 147, 22, 154, WHITE); tft.drawTriangle(15, 147, 29, 147, 22, 154, DGRAY); } } void drawC() { tft.fillRoundRect(44, 144, 40, 12, 3, BLUE); if (! c_pressed) { tft.drawRoundRect(44, 144, 40, 12, 3, LBLUE); tft.drawLine(46, 155, 81, 155, DBLUE); tft.drawLine(83, 146, 83, 153, DBLUE); tft.drawPixel(45, 154, DBLUE); tft.drawPixel(82, 154, DBLUE); tft.fillRoundRect(60, 146, 8, 8, 3, GRAY); tft.drawRoundRect(60, 146, 8, 8, 3, DGRAY); } else { tft.drawRoundRect(44, 144, 40, 12, 3, DBLUE); tft.drawLine(46, 155, 81, 155, LBLUE); tft.drawLine(83, 146, 83, 153, LBLUE); tft.drawPixel(45, 154, LBLUE); tft.drawPixel(82, 154, LBLUE); tft.fillRoundRect(60, 146, 8, 8, 3, WHITE); tft.drawRoundRect(60, 146, 8, 8, 3, DGRAY); } } void drawR() { tft.fillRoundRect(86, 145, 37, 12, 3, YELLOW); if (! r_pressed) { tft.drawRoundRect(86, 145, 37, 12, 3, LYELLOW); tft.drawLine(88, 156, 120, 156, DYELLOW); tft.drawLine(122, 147, 122, 154, DYELLOW); tft.drawPixel(87, 155, DYELLOW); tft.drawPixel(121, 155, DYELLOW); tft.fillTriangle(97, 154, 111, 154, 104, 147, GRAY); tft.drawTriangle(97, 154, 111, 154, 104, 147, DGRAY); } else { tft.drawRoundRect(86, 145, 37, 12, 3, DYELLOW); tft.drawLine(88, 156, 120, 156, LYELLOW); tft.drawLine(122, 147, 122, 154, LYELLOW); tft.drawPixel(87, 155, LYELLOW); tft.drawPixel(121, 155, LYELLOW); tft.fillTriangle(97, 154, 111, 154, 104, 147, WHITE); tft.drawTriangle(97, 154, 111, 154, 104, 147, DGRAY); } } void rgb_control() { //int tmp1; //tmp1 = Read(L_BTN); if (digitalRead(L_BTN) == LOW) { analogWrite(R_LED, 255); //Serial.println(analogRead(L_BTN)); } else { analogWrite(R_LED,0); } if (digitalRead(C_BTN) == LOW) { analogWrite(G_LED, 255); } else { analogWrite(G_LED,0); } if (digitalRead(R_BTN) == LOW) { analogWrite(B_LED, 255); } else { analogWrite(B_LED,0); } } // Callback for received data void receiveData(int byteCount) { while(Wire.available()) { // Get command cmd = Wire.read(); if (cmd == EXT_COM && byteCount == 3) { flg = 0x00; ext = 0x00; if (Wire.available()) ext = Wire.read(); if (Wire.available()) flg = Wire.read(); } else { // Cleanup I2C bus while(Wire.available()) { ext = Wire.read(); } } switch (cmd) { case COM_PING: autoresponse = OK_RSP; blink_red(); break; case COM_GET_TEMP: autoresponse = getInternalTemp(); break; default: autoresponse = ERR_RSP; break; } } } // Callback for sending data void answer() { Wire.write(autoresponse); } void blink_red() { digitalWrite(R_LED, HIGH); delay(100); digitalWrite(R_LED, LOW); } // Get the internal temperature of the arduino double getInternalTemp(void) { unsigned int wADC; double t; ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3)); ADCSRA |= _BV(ADEN); // enable the ADC delay(20); // wait for voltages to become stable. ADCSRA |= _BV(ADSC); // Start the ADC while (bit_is_set(ADCSRA,ADSC)); wADC = ADCW; t = (wADC - 324.31 ) / 1.22; return (t); } float readvcc() { float tmp = 0.0; // Read 1.1V reference against Avcc // set the reference to vcc and the measurement to the internal 1.1V reference #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) ADMUX = _BV(MUX5) | _BV(MUX0); #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) ADMUX = _BV(MUX3) | _BV(MUX2); #else // works on an Arduino 168 or 328 ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #endif delay(3); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversion while (bit_is_set(ADCSRA,ADSC)); // measuring uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both tmp = (high<<8) | low; tmp = (typVbg * 1023.0) / tmp; return tmp; } void tftPrintTest() { tft.setTextWrap(false); tft.fillScreen(ST7735_GREEN); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); tft.setTextSize(1); tft.println("Hello World!"); tft.setTextColor(ST7735_YELLOW); tft.setTextSize(2); tft.println("Hello World!"); tft.setTextColor(ST7735_GREEN); tft.setTextSize(3); tft.println("Hello World!"); tft.setTextColor(ST7735_BLUE); tft.setTextSize(4); tft.print(1234.567); delay(1500); tft.setCursor(0, 0); tft.fillScreen(ST7735_BLACK); tft.setTextColor(ST7735_WHITE); tft.setTextSize(0); tft.println("Hello World!"); tft.setTextSize(1); tft.setTextColor(ST7735_GREEN); tft.print(p, 6); tft.println(" Want pi?"); tft.println(" "); tft.print(8675309, HEX); // print 8,675,309 out in HEX! tft.println(" Print HEX!"); tft.println(" "); tft.setTextColor(ST7735_WHITE); tft.println("Sketch has been"); tft.println("running for: "); tft.setTextColor(ST7735_MAGENTA); tft.print(millis() / 1000); tft.setTextColor(ST7735_WHITE); tft.print(" seconds."); } void tftTest() { // tft.fillScreen(ST7735_BLACK); tft.drawRect(0, 0, 128, 160, ST7735_GREEN); tft.drawRect(1, 1, 126, 158, ST7735_WHITE); // Smile tft.fillCircle(64, 80, 40, ST7735_YELLOW); //tft.drawCircle(64, 80, 40, ST7735_BLUE); tft.fillRoundRect(45, 63, 10, 15, 3, ST7735_BLACK); tft.fillRoundRect(73, 63, 10, 15, 3, ST7735_BLACK); tft.fillTriangle(50, 95, 78, 95, 70, 105, ST7735_BLACK); tft.setCursor(33, 132); tft.setTextColor(ST7735_YELLOW); tft.setTextSize(2); tft.print("HELLO!"); // for (byte i = 1; i <= 31; i++) { // tft.drawRect(i * 2, i * 3, 128 - i * 4, 160 - i * 5, ST7735_WHITE); // delay(100); // //tft.drawRect(i * 2, i * 2, 128 - i * 4, 160 - i * 4, ST7735_BLACK); // } }