340 lines
6.4 KiB
C++
340 lines
6.4 KiB
C++
/////////////////////////////////////////
|
|
// HXbot HXlcd firmware /
|
|
// EoF 2016 EoF@itphx.ru /
|
|
/////////////////////////////////////////
|
|
|
|
#include <Wire.h>
|
|
#include <TroykaDHT11.h>
|
|
#include <LiquidCrystal.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
|
|
#define RED_PIN 10
|
|
#define GRN_PIN 9
|
|
#define LCD_BL 3
|
|
|
|
// 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
|
|
LiquidCrystal lcd(2, 4, 5, 6, 7, 8);
|
|
DHT11 dht(TEMP);
|
|
|
|
// эту константу (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;
|
|
|
|
void setup() {
|
|
|
|
if (DEBUG) {
|
|
Serial.println("GO!");
|
|
Serial.begin(9600);
|
|
}
|
|
|
|
// 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(RED_PIN, OUTPUT);
|
|
//digitalWrite(RED_PIN, LOW);
|
|
pinMode(GRN_PIN, OUTPUT);
|
|
//digitalWrite(GRN_PIN, LOW);
|
|
|
|
pinMode(R_LED, OUTPUT);
|
|
pinMode(G_LED, OUTPUT);
|
|
pinMode(B_LED, OUTPUT);
|
|
|
|
pinMode(LCD_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);
|
|
|
|
lcd.begin(16, 2);
|
|
analogWrite(LCD_BL, 255);
|
|
lcd.print("Hello world!");
|
|
|
|
dht.begin();
|
|
|
|
delay(2000);
|
|
lcd.clear();
|
|
}
|
|
|
|
void loop() {
|
|
if (digitalRead(FREE) == HIGH) {
|
|
analogWrite(GRN_PIN, 128);
|
|
}
|
|
else {
|
|
analogWrite(GRN_PIN, 0);
|
|
}
|
|
|
|
displayALL();
|
|
|
|
if (DEBUG) {
|
|
Serial.print("Vcc: ");
|
|
Serial.println(readvcc());
|
|
}
|
|
|
|
delay(500);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
void displayTH() {
|
|
int result;
|
|
result = dht.read();
|
|
|
|
lcd.clear();
|
|
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Temp:");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Hum:");
|
|
|
|
if (result == DHT_OK) {
|
|
lcd.setCursor(6, 0);
|
|
lcd.print(dht.getTemperatureC());
|
|
lcd.print(" C");
|
|
|
|
lcd.setCursor(6, 1);
|
|
lcd.print(dht.getHumidity());
|
|
lcd.print(" %");
|
|
}
|
|
else {
|
|
lcd.setCursor(6, 0);
|
|
lcd.print("ERROR");
|
|
lcd.setCursor(6, 1);
|
|
lcd.print("ERROR");
|
|
}
|
|
}
|
|
|
|
void displayLL() {
|
|
lcd.clear();
|
|
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Light:");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Loud:");
|
|
|
|
lcd.setCursor(8, 0);
|
|
lcd.print(analogRead(LIGHT));
|
|
|
|
lcd.setCursor(8, 1);
|
|
lcd.print(analogRead(LOUD));
|
|
}
|
|
|
|
void displayALL() {
|
|
int result;
|
|
result = dht.read();
|
|
|
|
lcd.clear();
|
|
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Li:");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Lo:");
|
|
|
|
lcd.setCursor(4, 0);
|
|
lcd.print(analogRead(LIGHT));
|
|
|
|
lcd.setCursor(4, 1);
|
|
lcd.print(analogRead(LOUD));
|
|
|
|
lcd.setCursor(9, 0);
|
|
lcd.print("T:");
|
|
lcd.setCursor(9, 1);
|
|
lcd.print("H:");
|
|
|
|
if (result == DHT_OK) {
|
|
lcd.setCursor(11, 0);
|
|
lcd.print(dht.getTemperatureC());
|
|
lcd.print("C");
|
|
|
|
lcd.setCursor(11, 1);
|
|
lcd.print(dht.getHumidity());
|
|
lcd.print(" %");
|
|
}
|
|
else {
|
|
lcd.setCursor(11, 0);
|
|
lcd.print("ERR");
|
|
lcd.setCursor(11, 1);
|
|
lcd.print("ERR");
|
|
}
|
|
}
|
|
|
|
// 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 red_on() {
|
|
digitalWrite(RED_PIN, HIGH);
|
|
}
|
|
|
|
void red_off() {
|
|
digitalWrite(RED_PIN, LOW);
|
|
}
|
|
|
|
void blink_red() {
|
|
red_on();
|
|
delay(100);
|
|
red_off();
|
|
}
|
|
|
|
// 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() {
|
|
byte i;
|
|
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;
|
|
}
|