Compare commits

..

36 Commits

Author SHA1 Message Date
Stephan Richter 4915c7bf51 Merge branch 'nano-revision-2.0' into nano-revision-2.1 4 weeks ago
Stephan Richter 948cb7de7b bugfix 4 weeks ago
Stephan Richter a681d189dc Merge branch 'nano-revision-2.0' into nano-revision-2.1 4 weeks ago
Stephan Richter 0a36f9bae4 re-ordered vars 4 weeks ago
Stephan Richter f308039696 switched back to DHT22 4 weeks ago
Stephan Richter 2af1db36ec Merge branch 'nano-revision-2.0' into nano-revision-2.1 1 month ago
Stephan Richter 7111fd706e added new project for nano with temp sensor and ir sender 1 month ago
Stephan Richter e9afd6fcce Merge branch 'nano-revision-2.0' into nano-revision-2.1 1 month ago
Stephan Richter c0ccaa4835 replaced sensor library to be able to use DHT11 1 month ago
Stephan Richter 8bdcfb6032 Merge branch 'nano-revision-2.0' into nano-revision-2.1 1 month ago
Stephan Richter b0c1c0a177 minor edits 1 month ago
Stephan Richter 6a2184f33d Merge branch 'nano-revision-2.0' into nano-revision-2.1 2 months ago
Stephan Richter 93ab76370a updated device list 2 months ago
Stephan Richter b6723b92fc Merge branch 'nano-revision-2.0' into nano-revision-2.1 2 months ago
Stephan Richter 7b54298e5f updated device list 2 months ago
Stephan Richter 769786e63a fixed revision 4 months ago
Stephan Richter 44fd0050e3 Merge branch 'nano-revision-2.0' into nano-revision-2.1 4 months ago
Stephan Richter 509f23e343 improving code 4 months ago
Stephan Richter 6e8016e718 Merge branch 'nano-revision-2.0' into nano-revision-2.1 5 months ago
Stephan Richter 970cdd6b97 improved voltage level for triggering 5 months ago
Stephan Richter d65586ba0b Merge branch 'nano-revision-2.0' into nano-revision-2.1 5 months ago
Stephan Richter 10a52cdfd7 preparing code for Device 4 5 months ago
Stephan Richter 43558e27ce bugfix in SerialTransceiver 5 months ago
Stephan Richter ef2488363d Merge branch 'nano-revision-2.0' into nano-revision-2.1 6 months ago
Stephan Richter b4278a77af updated SerialTransceiver 6 months ago
Stephan Richter a54897a4b5 Merge branch 'nano-revision-2.0' into nano-revision-2.1 6 months ago
Stephan Richter 40e785839b implemented new code "SerialTransceiver" 6 months ago
Stephan Richter fcbde966e3 Merge branch 'nano-revision-2.0' into nano-revision-2.1 10 months ago
Stephan Richter 0244d026c9 minor improvement 10 months ago
Stephan Richter 0f4c20bdce updated TempSender and LCDReceiver 10 months ago
Stephan Richter 70425f8d22 Merge branch 'nano-revision-2.0' into nano-revision-2.1 10 months ago
Stephan Richter a0dfb4c8f5 updated temp sender 10 months ago
Stephan Richter d0528773ec Merge branch 'nano-revision-2.0' into nano-revision-2.1 10 months ago
Stephan Richter 8e02709b32 fixed LCDReceiver for communication with RS485 rev 2.x boards 10 months ago
Stephan Richter d316dc83aa Entprellung implementiert 10 months ago
Stephan Richter 97a0e5b5b4 Dateien geordnet 10 months ago
  1. 26
      Software/LCDReceiver/LCDReceiver.ino
  2. 75
      Software/Sender/Sender.ino
  3. 38
      Software/SerialTransceiver/SerialTransceiver.ino
  4. 113
      Software/TempSender/TempSender.ino
  5. 194
      Software/TempSenderPlusIR/TempSenderPlusIR.ino

26
Software/LCDReceiver/LCDReceiver.ino

@ -23,17 +23,15 @@ @@ -23,17 +23,15 @@
#define PROGRAM "RS485-Nano 2.1 / LCDReceive 1.2"
// initialize the library by associating any needed LCD interface pin with the arduino pin number it is connected to
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
void setup() {
Serial.begin(115200);
init485(Max485_RO,Max485_RE,Max485_DE,Max485_DI); // library initialization:
invert485polarity(true);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.begin(16, 4);
// Print a message to the LCD.
printMessage(PROGRAM);
@ -42,13 +40,19 @@ void setup() { @@ -42,13 +40,19 @@ void setup() {
void printMessage(String s){
Serial.println(s);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(s);
if (s.length()>16) {
lcd.setCursor(0, 1);
s=s.substring(16);
s.trim();
lcd.print(s);
int line = 0;
int col = 0;
auto cstr = s.c_str();
for (int i=0;i<s.length();i++){
if (col == 0 && cstr[i] == ' ') continue;
if (cstr[i] == '{' || cstr[i] == '}') continue;
lcd.print(cstr[i]);
col++;
if (cstr[i]==',' || col==16){
line++;
col=0;
lcd.setCursor(col, line);
}
}
}

75
Software/Sender/Sender.ino

@ -9,7 +9,18 @@ @@ -9,7 +9,18 @@
// include the library code:
#include <SoftRS485.h>
#define PROGRAM "RS485-Nano 2.1 / Sender 1.1"
// 0=Test
// 1=Flur
// 2=Wohnzimmer
// 3=Bad EG
// 4=Treppenhaus
// 5=Arbeitszimmer
// 6=Bad OG
#define ID 0
#define PROGRAM "Sender"
#define SW_VERSION "1.3"
#define HW_VERSION "2.1"
#define BTN_INT 3 // button interrupt pin
#define Max485_RO 2 // read-output of Max485
@ -17,16 +28,12 @@ @@ -17,16 +28,12 @@
#define Max485_DE 8 // data enable of Max485
#define Max485_DI 9 // data input of Max485
#define TRESHOLD 100
#define ID 0
// 0=Test
// 1=Arbeitszimmer
// 2=Küche
// 3=Bad
#define TRESHOLD 1024
#define TRIGGER_LEVEL 200
//#define DEBUG
//#define LOG_TO_SERIAL
#define SEND_485
#define DEBUG
boolean raw_states[8];
boolean states[8];
@ -53,56 +60,54 @@ void setup(){ @@ -53,56 +60,54 @@ void setup(){
pinMode(20,INPUT_PULLUP);
pinMode(21,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2),isr,CHANGE);
// Print a message to the LCD.
Serial.println(PROGRAM);
attachInterrupt(digitalPinToInterrupt(BTN_INT),isr,CHANGE);
String s = "{nano:"+String(ID)+",hw:"+HW_VERSION+","+PROGRAM+":"+SW_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] = !digitalRead(14);
raw_states[1] = !digitalRead(15);
raw_states[2] = !digitalRead(16);
raw_states[3] = !digitalRead(17);
raw_states[4] = !digitalRead(18);
raw_states[5] = !digitalRead(19);
raw_states[6] = !(analogRead(20)>400);
raw_states[7] = !(analogRead(21)>400);
raw_states[0] = analogRead(14)<TRIGGER_LEVEL;
raw_states[1] = analogRead(15)<TRIGGER_LEVEL;
raw_states[2] = analogRead(16)<TRIGGER_LEVEL;
raw_states[3] = analogRead(17)<TRIGGER_LEVEL;
raw_states[4] = analogRead(18)<TRIGGER_LEVEL;
raw_states[5] = analogRead(19)<TRIGGER_LEVEL;
raw_states[6] = analogRead(20)<TRIGGER_LEVEL;
raw_states[7] = analogRead(21)<TRIGGER_LEVEL;
#ifdef LOG_TO_SERIAL
for (int i=0;i<8;i++){
Serial.print(" "); Serial.print(raw_states[i]); Serial.print(" ");
Serial.print(" ");
Serial.print(raw_states[i]);
Serial.print(" ");
}
Serial.println();
#endif
}
#ifdef SEND_485
void send(int btn, long duration){
String s = "{nano:"+String(ID)+",btn:"+String(btn)+",dura:"+String(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();
boolean pause = true;
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;
#ifdef DEBUG
if (capacitor[i]) {
Serial.print("cap "); Serial.print(i); Serial.print(": "); Serial.println(capacitor[i]);
}
#endif
// if the capacitor reaches a certain treshold, the state is changed
boolean new_state = capacitor[i]>TRESHOLD;
@ -110,13 +115,9 @@ void loop(){ @@ -110,13 +115,9 @@ void loop(){
// when the state changes, the duration of the last state is calculated
if (states[i] != new_state){
long diff = now - times[i];
long diff = (now - times[i])/1000;
times[i] = now;
#ifdef SEND_485
if (states[i]){ // old state was HIGH → we are going LOW
send(i+1,diff);
}
#endif
if (states[i]) send(i+1,diff); // old state was HIGH → we are going LOW
states[i] = new_state;
}
}

38
Software/SerialTransceiver/SerialTransceiver.ino

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
/*
* Demonstrates how to use LCDisplay in conjunction with SoftRS485:
*
* The main _loop_ of this program listens on the RS485 bus.
* Whenever a message is received from the bus, it is displayed on the LCD.
*/
// include the library code:
#include <SoftRS485.h>
#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 PROGRAM "{hw:RS485-Nano rev 2.1,firmware:Transceiver,version:1.0}"
String message = "";
char c;
void setup() {
Serial.begin(115200);
init485(Max485_RO,Max485_RE,Max485_DE,Max485_DI); // library initialization:
send485(PROGRAM);
}
void loop() {
if (available485()) Serial.println(get485message());
while (Serial.available()) {
c = (char)Serial.read();
if (c == '\n') {
send485(message.c_str());
message = "";
} else {
message += c;
}
}
}

113
Software/TempSender/TempSender.ino

@ -4,41 +4,62 @@ @@ -4,41 +4,62 @@
* 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 <SoftRS485.h>
#include <AM2302-Sensor.h>
#include <SimpleDHT.h>
// 0=Test
// 1=Flur
// 2=Wohnzimmer
// 3=Bad EG
// 4=Treppenhaus
// 5=Arbeitszimmer
// 6=Bad OG
#define PROGRAM "RS485-Nano 2.1 / TempSender 1.1"
#define ID 0
#define HW_VERSION "2.1"
#define PROGRAM "TempSender"
#define SW_VERSION "1.5"
#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 TRIGGER_LEVEL 200
#define DHT_PIN 4
#define TRESHOLD 100000 // 100ms
#define PERIOD 100000000 // 100s
#define ID 3
// 0=Test
// 1=Arbeitszimmer
// 2=Küche
// 3=Bad
//#define DEBUG
//#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 = PERIOD;
unsigned long sensor_time = 0;
// these values are used for temperature processing
SimpleDHT22 sensor(DHT_PIN);
float temperature = 0;
float humidity = 0;
int err = SimpleDHTErrSuccess;
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);
@ -50,67 +71,73 @@ void setup(){ @@ -50,67 +71,73 @@ void setup(){
pinMode(20,INPUT_PULLUP);
pinMode(21,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2),isr,FALLING);
// Print a message to the LCD.
Serial.println(PROGRAM);
attachInterrupt(digitalPinToInterrupt(BTN_INT),isr,CHANGE);
String s = "{nano:"+String(ID)+",hw:"+HW_VERSION+","+PROGRAM+":"+SW_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(){
states[0] = !digitalRead(14);
states[1] = !digitalRead(15);
states[2] = !digitalRead(16);
states[3] = !digitalRead(17);
states[4] = !digitalRead(18);
states[5] = !digitalRead(19);
states[6] = !(analogRead(20)>200);
states[7] = !(analogRead(21)>200);
raw_states[0] = analogRead(14)<TRIGGER_LEVEL;
raw_states[1] = analogRead(15)<TRIGGER_LEVEL;
raw_states[2] = analogRead(16)<TRIGGER_LEVEL;
raw_states[3] = analogRead(17)<TRIGGER_LEVEL;
raw_states[4] = analogRead(18)<TRIGGER_LEVEL;
raw_states[5] = analogRead(19)<TRIGGER_LEVEL;
raw_states[6] = analogRead(20)<TRIGGER_LEVEL;
raw_states[7] = analogRead(21)<TRIGGER_LEVEL;
#ifdef LOG_TO_SERIAL
for (int i=0;i<8;i++){
Serial.print(" "); Serial.print(states[i]); Serial.print(" ");
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
void send(int btn){
String s = "{nano:"+String(ID)+",btn:"+String(btn)+"}";
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++){
if (states[i]){
delay(1);
if (now - times[i] > TRESHOLD){
#ifdef SEND_485
send(i+1);
#endif
// 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;
}
states[i] = 0;
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())+"}";
if ((err = sensor.read2(&temperature, &humidity, NULL)) == SimpleDHTErrSuccess) {
String s = "{nano:"+String(ID)+",temp:"+String(temperature,1)+",humi:"+String(humidity,1)+"}";
send485(s.c_str());
#ifdef LOG_TO_SERIAL
Serial.println(s);
#endif
}
}
}

194
Software/TempSenderPlusIR/TempSenderPlusIR.ino

@ -0,0 +1,194 @@ @@ -0,0 +1,194 @@
/*
* 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 <SoftRS485.h>
#include <SimpleDHT.h>
#include <TinyIRSender.hpp>
// 0=Test
// 1=Flur
// 2=Wohnzimmer
// 3=Bad EG
// 4=Treppenhaus
// 5=Arbeitszimmer
// 6=Bad OG
#define ID 0
#define PROGRAM "Temp+IR"
#define SW_VERSION "0.1"
#define HW_VERSION "2.1"
#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 TRIGGER_LEVEL 200
#define DHT_PIN 4
#define PERIOD 100000000 // 100s
#define IR_PIN 5
#define REPEATS 2
//#define DEBUG
//#define LOG_TO_SERIAL
#define SEND_485
boolean raw_states[8];
boolean states[8];
unsigned long capacitor[8];
unsigned long times[8];
unsigned long sensor_time = 0;
// these values are used for temperature processing
SimpleDHT11 sensor(DHT_PIN);
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
// these constants are used for message parsing in handle(message)
const char* outer_delimiter = "{,}";
const char* inner_delimiter = ":";
void setup(){
for (int i=0; i<8;i++) {
capacitor[i] = 0;
raw_states[i] = LOW;
states[i] = LOW;
}
Serial.begin(115200);
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);
String s = "{nano:"+String(ID)+",hw:"+HW_VERSION+","+PROGRAM+":"+SW_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)<TRIGGER_LEVEL;
raw_states[1] = analogRead(15)<TRIGGER_LEVEL;
raw_states[2] = analogRead(16)<TRIGGER_LEVEL;
raw_states[3] = analogRead(17)<TRIGGER_LEVEL;
raw_states[4] = analogRead(18)<TRIGGER_LEVEL;
raw_states[5] = analogRead(19)<TRIGGER_LEVEL;
raw_states[6] = analogRead(20)<TRIGGER_LEVEL;
raw_states[7] = analogRead(21)<TRIGGER_LEVEL;
#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 handle(String message){
#ifdef LOG_TO_SERIAL
Serial.println(message);
#endif
unsigned int ir_cmd = 0;
unsigned int ir_addr = 0;
unsigned int nano = 0;
const char* outer_state = NULL;
const char* inner_state = NULL;
char* token = strtok_r(message.c_str(), outer_delimiter, &outer_state);
while (token != NULL) {
char* key = strtok_r(token,inner_delimiter,&inner_state);
char* val = strtok_r(NULL,inner_delimiter,&inner_state);
if (strcmp(key,"nano")==0) nano = atoi(val);
if (strcmp(key,"addr")==0) ir_addr = atoi(val);
if (strcmp(key,"ir")==0) ir_cmd = atoi(val);
token=strtok_r(NULL, outer_delimiter, &outer_state);
}
if (nano == ID){ // the message is addressed to us!
if (ir_addr && ir_cmd){
#ifdef LOG_TO_SERIAL
Serial.print("Sending 0x");
Serial.print(ir_cmd,HEX);
Serial.print(" to 0x");
Serial.println(ir_addr,HEX);
#endif
sendNECMinimal(IR_PIN, ir_addr, ir_cmd, REPEATS);
}
}
}
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;
if ((err = sensor.read(&temperature, &humidity, NULL)) == SimpleDHTErrSuccess) {
String s = "{nano:"+String(ID)+",temp:"+String((int)temperature)+",humi:"+String((int)humidity)+"}";
#ifdef LOG_TO_SERIAL
Serial.println(s);
#endif
send485(s.c_str());
}
}
if (available485()) handle(get485message());
}
Loading…
Cancel
Save