Node firmware - and adding new data/ sensors to a node

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Node firmware - and adding new data/ sensors to a node

J.sim
Hello There,

just trying to update the firmware in my new node to update the key to the same as my gateway.

what board type do i use? I am currently getting a avrdude no tin sync error.

once i can get that to work i will follow you up on how to program in more sensors for a node. Im a little shy on experience in this field and still learning so i haven't quite linked all the parts of doing it together yet.

Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Node firmware - and adding new data/ sensors to a node

vysocan
Administrator
Hello Jason,

download the code from https://github.com/vysocan/remote_1_4_RFM69 assuming you sepeak about wireless node.

Then edit these defines:
// Radio
#define NODEID      14
#define NETWORKID   100
#define GATEWAYID   1
#define FREQUENCY   RF69_868MHZ //Match this with the version of your gateway (others: RF69_433MHZ, RF69_915MHZ)
#define KEY         "ABCDABCDABCDABCD" //has to be same 16 characters/bytes on all nodes, not more not less!
#define ENABLE_ATC  //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75

NODEID is number from 2 .. 250, do not number the nodes with same NODEID!
NETWORKID   100, GATEWAYID   1 leave as is.
FREQUENCY   RF69_868MHZ depends on your country, leave it as is or put RF69_915MHZ, RF69_433MHZ will not work as it need different radio module.
KEY         "ABCDABCDABCDABCD" needs to match the KEY of gateway.
ENABLE_ATC leave as is for battery powered nodes
ATC_RSSI -75 is threshold for AUTO TRANSMISSION CONTROL, you can safely leave as it is.

To upload the sketch to radio node first select the right target:
Select Tools > Board menu > Arduino Pro or Pro Mini, then choose Tools > Processors > ATmega328P (5V / 16Mhz)
All nodes run on 3V3 but on 16Mhz, as there is no such option choose  always (5V / 16Mhz), it will not do any harm.

Then like for the gateway connect the FTDI 6 pin serial programmer and press upload.

If all is good, you should see new sensors in Node tab of gateway web interface. Wireless node usually report temperature, battery voltage if battery is connected, charging status and own radio power level. Power level is useful to see how good the signal is when AUTO TRANSMISSION CONTROL is enabled, lower is better.

Adam
Reply | Threaded
Open this post in threaded view
|

Re: Node firmware - and adding new data/ sensors to a node

vysocan
Administrator
Hello Jason,

I have put it as blog post along with other details, let me know if it is readable. https://openhomesecurity.blogspot.cz/2018/01/wireless-node-copnfiguration.html
Reply | Threaded
Open this post in threaded view
|

RE: Node firmware - and adding new data/ sensors to a node

J.sim

J ok. I had a quick look. Looks ok so far but I will go through the motions of it all before I comment any further….

 

Btw … configuration doesn’t have a ‘p’ in it.  ;)

 

From: vysocan [via OHS] [mailto:[hidden email]]
Sent: Wednesday, 17 January 2018 5:16 AM
To: J.sim <[hidden email]>
Subject: Re: Node firmware - and adding new data/ sensors to a node

 

Hello Jason,

I have put it as blog post along with other details, let me know if it is readable. https://openhomesecurity.blogspot.cz/2018/01/wireless-node-copnfiguration.html


If you reply to this email, your message will be added to the discussion below:

http://ohs.561.n8.nabble.com/Node-firmware-and-adding-new-data-sensors-to-a-node-tp80p82.html

To unsubscribe from Node firmware - and adding new data/ sensors to a node, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: Node firmware - and adding new data/ sensors to a node

Fillipsonn
In reply to this post by vysocan
Hello Adam,

Is the situation with wired nodes the same, or there is any differencies in the data blocks?
It looks very similar in the code.
I'm trying to transform code for wirelles relay module to wired one.

Thanks
Filip
Reply | Threaded
Open this post in threaded view
|

Re: Node firmware - and adding new data/ sensors to a node

vysocan
Administrator
Hello Filip,

data structure is identical. I have also wired node with relay. I'm including my code as an example, check the "// Data to relays" . And also I have there relay auto off function. Rest should be similar to standard wired node for Key. The relay opens my garage door, or actually just simulate press of button for 500ms.

// Remote node for RS485, iButton, and LM335 temp.
// Board v.1.10
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466

#include <OneWire.h>
#include <LibRS485.h>
#include <avr/eeprom.h> // Global configuration for in chip EEPROM

// Pins
#define RELAY_1    A0

#define MY_ADDRESS 2  // 0 is gateway, 15 is multicast
#define LED_GREEN 9   // iButton probe 
#define LED_RED 8     // iButton probe 
#define SPEAKER 6     // Speaker pin
#define LM335 A6      // Temp. sensor
#define DE 4          // RS 485 DE pin
#define VERSION 110   // Version of EEPROM struct
#define REG_LEN    21 // size of one conf. element
#define REG_REPEAT 10 // repeat sending

OneWire ds(5);        // Dallas reader on pin with  4k7 pull-up rezistor
RS485_msg msg; 

// Global variables
int8_t  i;
uint8_t addr[8];      // Dallas chip
uint8_t mode = 0;
uint8_t pos;
uint8_t repeat = 0;
uint8_t version = 0;
long    previousMillis = 0;
long    readerMillis   = 0;
long    tempMillis     = 0;
long    relayMillis    = 0;
uint8_t relay1 = 0;

// Notes and LEDs patterns
char *goodkey  = "G1,,G5,,g0,.";
char *wrongkey = "R1,,R1,,r0,.";
char *auth0    = "R5,r0,.";
char *auth1    = "R5,r0,,,,.";
char *auth2    = "R5,r0,,,,,,.";
char *auth3    = "R5,r0,,,,,,,,.";
char *p        = ".";
char *ok       = "G,g,,,,,,,,,.";
char *armed    = "R,r,,,,,,,,,.";
char *arming   = "R7,r5,R7,r0,,,,,,,,.";
int notes[] = { NOTE_A3, NOTE_B3, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4 };

struct config_t {
  uint16_t version;
  char     reg[REG_LEN * 2];
} conf; 

// Float conversion 
union u_tag {
    uint8_t  b[4]; 
    float    fval;
} u;


// Registration 
void send_conf(){ 
  delay(MY_ADDRESS*100); // Wait some time to avoid contention
  msg.address = 0;
  msg.ctrl = FLAG_DTA;
  msg.data_length = REG_LEN + 1; // Add 'R'
  pos = 0;
  while (pos < sizeof(conf.reg)) {
    msg.buffer[0] = 'R'; // Registration flag
    for (uint8_t ii=0; ii < REG_LEN; ii++){ msg.buffer[1+ii] = conf.reg[pos+ii]; }
    repeat = 0;
    do {
      i = RS485.msg_write(&msg);
      tone(SPEAKER, notes[pos/REG_LEN]);  delay(100); noTone(SPEAKER); delay(100);
      repeat++;
    } while ((i < 1) && (repeat < REG_REPEAT));
    pos += REG_LEN;
  }
  msg.buffer[0] = 0; msg.data_length = 0; // Clear buffer
}

// Set defaults on first time
void setDefault(){
  conf.version = VERSION;   // Change VERSION to take effect
  conf.reg[0]  = 'K';       // Key
  conf.reg[1]  = 'i';       // iButton
  conf.reg[2]  = 0;         // Local address
  conf.reg[3]  = B00000000; // Default setting
  conf.reg[4]  = B00011110; // Default setting, group=16, disabled
  for (uint8_t ii=0; ii < 17; ii++){ conf.reg[5+ii] = 0;} // Placeholder for name
  conf.reg[21] = 'I';       // Input
  conf.reg[22] = 'D';       // Digital
  conf.reg[23] = 0;         // Local address
  conf.reg[24] = B00000000; // Default setting
  conf.reg[25] = B00011110; // Default setting, group=16, disabled
  for (uint8_t ii=0; ii < 17; ii++){ conf.reg[26+ii] = 0;}
}

void setup() {
  // Set pins
  pinMode(RELAY_1, OUTPUT); digitalWrite(RELAY_1, 0);
  pinMode(DE, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_RED, OUTPUT);  
  pinMode(LM335, INPUT);  
  
  RS485.begin(19200, MY_ADDRESS);

  eeprom_read_block((void*)&conf, (void*)0, sizeof(conf)); // Read current configuration
  if (conf.version != VERSION) {
    setDefault();
    eeprom_update_block((const void*)&conf, (void*)0, sizeof(conf)); // Save current configuration
  }
  
  delay(1000);
  send_conf(); 
 
  previousMillis = millis();
  readerMillis   = millis(); 
  tempMillis     = millis();
  relayMillis    = millis(); 
}

void loop() {
  // Look for incomming transmissions
  if (RS485.msg_read(&msg) > 0) {
    // Commands from gateway
    if (msg.ctrl == FLAG_CMD) {
      if (msg.data_length == 1)  send_conf(); // Request for registration
      if ((msg.data_length >= 10) && (msg.data_length <= 20)) mode = msg.data_length; // Auth. commands
    }
    // Configuration change 
    if (msg.ctrl == FLAG_DTA && msg.buffer[0]=='R') {
      // Replace part of conf string with new paramters.
      pos = 0; 
      while (((conf.reg[pos] != msg.buffer[1]) || (conf.reg[pos+1] != msg.buffer[2]) || (conf.reg[pos+2] != msg.buffer[3])) && (pos < sizeof(conf.reg))) {
        pos += REG_LEN; // size of one conf. element
      }      
      if (pos < sizeof(conf.reg)) {
        for (uint8_t ii=0; ii < msg.data_length-1; ii++){ conf.reg[pos+ii]=msg.buffer[1+ii]; }
        // Save it to EEPROM
        conf.version = VERSION;
        eeprom_update_block((const void*)&conf, (void*)0, sizeof(conf)); // Save current configuration
        // Send this piece back for re-registration
        msg.address = 0; msg.ctrl = FLAG_DTA;
        repeat = 0;
        do {
          i = RS485.msg_write(&msg);
          tone(SPEAKER, notes[pos/REG_LEN]);  delay(100); noTone(SPEAKER); delay(100);
          repeat++;
        } while ((i < 0) && (repeat < REG_REPEAT));
        msg.buffer[0] = 0; msg.data_length = 0; // Clear buffer
      }
    }
    // Data to relays
    if (msg.ctrl == FLAG_DTA && msg.buffer[0]=='I') { // Input
      tone(SPEAKER, notes[1]);  delay(100); noTone(SPEAKER); delay(100);
      u.b[0] = msg.buffer[2]; u.b[1] = msg.buffer[3]; u.b[2] = msg.buffer[4]; u.b[3] = msg.buffer[5]; 
      switch((byte)msg.buffer[1]){
        case 0: digitalWrite(RELAY_1, (byte)u.fval);
          relayMillis = millis();
          relay1 = 1;
          tone(SPEAKER, notes[1]);  delay(100); noTone(SPEAKER); delay(100);
          break;
      }
    }
  }

  // Relay auto Off
  if ((relay1 > 0) && ((long)(millis() - relayMillis) >= 500)) {
    digitalWrite(RELAY_1, 0);
    relay1 = 0;
    // Send message back to GW
    u.fval = (float)0;
    msg.address = 0;
    msg.ctrl = FLAG_DTA;
    msg.data_length = 7;
    msg.buffer[0] = 'I'; // Inpput
    msg.buffer[1] = 'D'; // Digital
    msg.buffer[2] = 0;   // local address
    msg.buffer[3] = u.b[0]; msg.buffer[4] = u.b[1]; msg.buffer[5] = u.b[2]; msg.buffer[6] = u.b[3];    
    i = RS485.msg_write(&msg);
    tone(SPEAKER, notes[1]);  delay(100); noTone(SPEAKER); delay(100);
    msg.buffer[0] = 0; msg.data_length = 0; // Clear buffer
  }
    
  // Tone and leds
  if ((long)(millis() - previousMillis) >= 200) {
    previousMillis = millis();   
    if (*p == '.') {
      // reset all sound and LED
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_GREEN, LOW);
      noTone(SPEAKER);
      // change the mode
      switch (mode) {
        case 10: p = arming; break;
        case 11: p = auth0; break;
        case 12: p = auth1; break;
        case 13: p = auth2; break;
        case 14: p = auth3; break;          
        case 15: p = armed; break;
        default: p = ok; break; // Case 20
      }
    } 
    while (*p != ',') {
      switch (*p) {
        case 'G': digitalWrite(LED_GREEN, HIGH); break;
        case 'g': digitalWrite(LED_GREEN, LOW); break;
        case 'R': digitalWrite(LED_RED, HIGH); break;
        case 'r': digitalWrite(LED_RED, LOW); break;
        case '1'...'9': tone(SPEAKER, notes[*p-49]); break;
        case '0': noTone(SPEAKER); break;  
        default: break;
      }
      p++;  
    }
    p++;
    // check iButton between notes but only every 3000 ms
    if ((unsigned long)(millis() - readerMillis) > 3000) {
      if ( !ds.search(addr)) {
        ds.reset_search();
      } else { // we have chip at reader
        readerMillis = millis();
        // Check of iButton crc
        if ( OneWire::crc8( addr, 7) == addr[7]) { // valid crc, send to master
          msg.address = 0;
          msg.ctrl = FLAG_DTA;
          msg.data_length = 8;
          memcpy(msg.buffer, addr, msg.data_length);
          i = RS485.msg_write(&msg);
          p = goodkey; // play 
          ds.reset_search();
        } else { // crc not valid
          p = wrongkey; // play 
          ds.reset_search();
        }
      }
    } // End iButton
  }  
}

Reply | Threaded
Open this post in threaded view
|

Re: Node firmware - and adding new data/ sensors to a node

Fillipsonn
Thank you very much!
Your code works without any problem.

Filip