/* * Demonstrates how to use Read Buttons in conjunction with SoftRS485: * * If a button is pressed, a corresponding flag is set. * The main loop checks for the state of those flags and * sends a message on the RS485 bus whenever a flag is set. * * Additionally, the temperature is read from a DHT22 sensor once per minute */ // include the library code: #include #include #define VERSION "1.2" #define BTN_INT 3 // button interrupt pin #define Max485_RO 2 // read-output of Max485 #define Max485_RE 3 // not-read-enable of Max485 #define Max485_DE 8 // data enable of Max485 #define Max485_DI 9 // data input of Max485 #define TRESHOLD 1024 #define DHT_PIN 4 #define PERIOD 100000000 // 100s #define ID 0 // 0=Test // 1=Arbeitszimmer // 2=Küche // 3=Bad //#define LOG_TO_SERIAL #define SEND_485 AM2302::AM2302_Sensor am2302{DHT_PIN}; boolean raw_states[8]; boolean states[8]; unsigned long capacitor[8]; unsigned long times[8]; unsigned long sensor_time = 0; void setup(){ for (int i=0; i<8;i++) { capacitor[i] = 0; raw_states[i] = LOW; states[i] = LOW; } Serial.begin(115200); am2302.begin(); init485(Max485_RO,Max485_RE,Max485_DE,Max485_DI); // library initialization: pinMode(BTN_INT,INPUT_PULLUP); pinMode(14,INPUT_PULLUP); pinMode(15,INPUT_PULLUP); pinMode(16,INPUT_PULLUP); pinMode(17,INPUT_PULLUP); pinMode(18,INPUT_PULLUP); pinMode(19,INPUT_PULLUP); pinMode(20,INPUT_PULLUP); pinMode(21,INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(BTN_INT),isr,CHANGE); // Print a message to the LCD. String s = "{nano:"+String(ID)+",revision:2.1,TempSender:"+VERSION+"}"; Serial.println(s); send485(s.c_str()); #ifdef LOG_TO_SERIAL Serial.println("14 15 16 17 18 19 20 21"); #endif } void isr(){ raw_states[0] = analogRead(14)<400; raw_states[1] = analogRead(15)<400; raw_states[2] = analogRead(16)<400; raw_states[3] = analogRead(17)<400; raw_states[4] = analogRead(18)<400; raw_states[5] = analogRead(19)<400; raw_states[6] = analogRead(20)<400; raw_states[7] = analogRead(21)<400; #ifdef LOG_TO_SERIAL for (int i=0;i<8;i++){ Serial.print(" "); Serial.print(raw_states[i]); Serial.print(" "); } Serial.println(); #endif } void send(int btn, long duration){ String s = "{nano:"+String(ID)+",btn:"+String(btn)+",ms:"+String(duration)+"}"; #ifdef SEND_485 for (int i = 0; i<10; i++){ if (send485(s.c_str())) break; Serial.println("collision detected, trying again:"); } #else Serial.println(s); #endif } void loop(){ unsigned long now = micros(); for (int i=0;i<8;i++){ // we emulate a capacitor: // when the button is pressed, it slowly loads, if the button is released, it unloads. capacitor[i] = raw_states[i] ? capacitor[i]+1 : capacitor[i]>>1; // if the capacitor reaches a certain treshold, the state is changed boolean new_state = capacitor[i]>TRESHOLD; // TODO: drop state after a maximum HIGH time // when the state changes, the duration of the last state is calculated if (states[i] != new_state){ long diff = (now - times[i])/1000; times[i] = now; if (states[i]) send(i+1,diff); // old state was HIGH → we are going LOW states[i] = new_state; } } if (now - sensor_time > PERIOD){ sensor_time = now; auto status = am2302.read(); if (status == 0){ String s = "{nano:"+String(ID)+",temp:"+String(am2302.get_Temperature())+",humi:"+String(am2302.get_Hunidity())+"}"; send485(s.c_str()); } } }