Sending data two way's.

Started by JimJim, December 08, 2013, 01:25:27 PM

JimJim

Hi I am trying to send data, two way's on two Moteino.  Just A simple push switch on pin 5 and the led on pin 9.
One (1 Moteino) pin 5 goes high and the other (2 Moteino) pin 9 goes high. 
One (2 Moteino) pin 5 goes high and the other (1 Moteino) pin 9 goes high.
One (1 Moteino) pin 5 goes low and the other (2 Moteino) pin 9 goes low. 
One (2 Moteino) pin 5 goes low and the other (1 Moteino) pin 9 goes low.
and so on. 

As of now one led will light up as you push the switch on the other Moeino.

Here is my arduino Sketch,  if you people can help great if not ok. 





int led = 9;
 const int ledPin =  9;
 
 int buttonState = 0;
const int buttonPin = 5;

#include <RFM12B.h>
#include <avr/sleep.h>

// By default the SPI-SS line used is D10 on Atmega328. You can change it by calling .SetCS(pin) where pin can be {8,9,10}
#define NODEID           1  //network ID used for this unit
#define NETWORKID       99  //the network ID we are on
#define GATEWAYID     2  //the node ID we're sending to
#define SERIAL_BAUD 115200


uint8_t KEY[] = "ABCDABCDABCDABCD";


RFM12B radio;

typedef struct { int power1; }PayloadRX;      // create structure - a neat way of packaging data for RF comms
PayloadRX emonrx;  

typedef struct {int  power2;} 
 PayloadTX; 
 PayloadTX emontx;  
 
 

void setup()
{
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  radio.Encrypt(KEY);      //comment this out to disable encryption
  Serial.begin(SERIAL_BAUD);
  Serial.println("Listening...");
  pinMode (led, OUTPUT);
  int button = 5;
}

void loop()
{
  
  
  buttonState = digitalRead(buttonPin);
  

  emonrx.power1=emonrx.power1=buttonState;
  
  
  
  
  if (radio.ReceiveComplete())
  {
    if (radio.CRCPass())
    {
       emontx=*(PayloadTX*) radio.Data; 
       
       
    radio.Wakeup();
    radio.Send(GATEWAYID, &emonrx, sizeof emonrx);
 

  Serial.print("power1: "); Serial.println(emonrx.power1); 
  
  Serial.print("power2: "); Serial.println(emontx.power2);
  
     
     
      
   
      if (emontx.power2 == HIGH) {     
        // turn LED on:    
        digitalWrite(ledPin, HIGH);  
      } 
   else 

        // turn LED off:
        digitalWrite(ledPin, LOW); 
        delay(100);
       {
       
       
       
       
  delay(1000);
    
       }
    }
  }
}





int buttonState = 0;
const int buttonPin = 5;

int led = 9;
 const int ledPin =  9;
 
#include <RFM12B.h>
#include <avr/sleep.h>


// By default the SPI-SS line used is D10 on Atmega328. You can change it by calling .SetCS(pin) where pin can be {8,9,10}
#define NODEID        2  //network ID used for this unit
#define NETWORKID    99  //the network ID we are on
#define GATEWAYID     1  //the node ID we're sending to
#define ACK_TIME     50  // # of ms to wait for an ack
#define SERIAL_BAUD  115200


uint8_t KEY[] = "ABCDABCDABCDABCD";

int interPacketDelay = 1000; //wait this many ms between sending packets
char input = 0;


RFM12B radio;
byte sendSize=0;

typedef struct { int power2; } PayloadTX;      // create structure - a neat way of packaging data for RF comms
PayloadTX emontx;  

typedef struct {int  power1;} 
 PayloadRX; 
 PayloadRX emonrx; 

void setup()
{
  Serial.begin(SERIAL_BAUD);
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  radio.Encrypt(KEY);
  radio.Sleep(); //sleep right away to save power
  Serial.println("Transmitting...\n\n");
  pinMode (led, OUTPUT);
  int button1 = 5;
}

void loop()
{
  
  

  
 buttonState = digitalRead(buttonPin);
  

  emontx.power2=emontx.power2=buttonState;


 
 
  if (Serial.available() > 0) {
   input = Serial.read();
   if (input >= 48 && input <= 57) //[1..9] = {100..900}ms; [0]=1000ms
    {
      interPacketDelay = 100 * (input-48);
      if (interPacketDelay == 0) interPacketDelay = 1000;
      Serial.print("\nChanging delay to ");
      Serial.print(interPacketDelay);
      Serial.println("ms\n");
    }
  }

  // emonrx=*(PayloadRX*) radio.Data; 
  
  radio.Wakeup();
  radio.Send(GATEWAYID, &emontx, sizeof emontx);
  

 

  Serial.print("power2: "); Serial.println(emontx.power2); 
  
  
    

  
   Serial.print("power1: "); Serial.println(emonrx.power1); 
 
  
  
   
      if (emonrx.power1 == HIGH) {     
        // turn LED on:    
        digitalWrite(ledPin, HIGH);  
      } 
   else 

        // turn LED off:
        digitalWrite(ledPin, LOW); 
        delay(100);
       {
       
       
         delay(1000);
       

           
      
    }
  }

Felix

Jim - at a glance I believe the LED control examples are doing something very similar: https://github.com/LowPowerLab/RFM12B/tree/master/Examples

JimJim

But when Moeino 2 switch goes high Moeino 1 led pin9 will not go high,  this is what I need help on?

KanyonKris

What are you seeing on the serial monitor for Moteino 2? I find this to be very useful for debugging. Hook up your FTDI cable to Moteino 2 and in the Arduino IDE select Tools | Serial Monitor. Set to 115200 baud. Add:

Serial.println("The radio received routine was called");

lines to your code with appropriate messages to check that subroutines got called or not, print the value of variables, etc.

JimJim

Here is some simple code,  I would like to know how to send the data both
way's? 

(1Moteino pin5 and pin0) send data to 2Moteino.
(2Moteino pin5 and pin0) send data to 1Moteino.





TX 1 Moteino
int val;
int new_val;
//int power1;
int buttonState = 0;
const int buttonPin = 5;

#include <RFM12B.h>


#define NODEID        2  
#define NETWORKID    99  
#define GATEWAYID     1  
#define SERIAL_BAUD  115200
char input = 0;
int interPacketDelay = 1000;
uint8_t KEY[] = "ABCDABCDABCDABCD";

typedef struct  { int power1, power2; } PayloadTX;
PayloadTX emontx; 
 
RFM12B radio;


void setup()
{
  Serial.begin(SERIAL_BAUD);
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  radio.Encrypt(KEY);
  Serial.println("Transmitting...\n\n");
}
void loop()
{
   val = analogRead(0);
  
  new_val = map(val, 0, 1023, 253, 0); 
  
 buttonState = digitalRead(buttonPin);
  
 emontx.power1=new_val;
 emontx.power2=buttonState;

   if (Serial.available() > 0) {
    input = Serial.read();
    if (input >= 48 && input <= 57) //[1..9] = {100..900}ms; [0]=1000ms
    {
      interPacketDelay = 100 * (input-48);
      if (interPacketDelay == 0) interPacketDelay = 1000;
      Serial.print("\nChanging delay to ");
      Serial.print(interPacketDelay);
      Serial.println("ms\n");
    }
  }

  Serial.println("Sending");
 
  radio.Send(GATEWAYID, &emontx, sizeof emontx);
  
  Serial.print("power1: "); Serial.println(emontx.power1); 
  Serial.print("power2: "); Serial.println(emontx.power2); 
 
delay(1000);
  
}







RX 1 Moteino
const int ledPin =  9;

 #include <RFM12B.h>

 #define NODEID           1  
 #define NETWORKID       99  
 #define SERIAL_BAUD 115200
 uint8_t KEY[] = "ABCDABCDABCDABCD";

 RFM12B radio;

 typedef struct {int power1, power2;} 
 PayloadTX; 
 PayloadTX emontx;  

 void setup()
 {
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  radio.Encrypt(KEY);     
  Serial.begin(SERIAL_BAUD);
  Serial.println("Listening...");
  pinMode (ledPin, OUTPUT);
 }

 void loop()
 {
  if (radio.ReceiveComplete())
  {
    if (radio.CRCPass())
    {

      emontx=*(PayloadTX*) radio.Data; 

      Serial.print("power1: "); 
      Serial.println(emontx.power1); 
      Serial.print("power2: "); 
      Serial.println(emontx.power2); 
      
if (emontx.power2 == HIGH) {     
        // turn LED on:    
        digitalWrite(ledPin, HIGH);  
      } 
      else {
        // turn LED off:
        digitalWrite(ledPin, LOW); 
        delay(1000);

      }
    }
  }
}

Felix

2 way communication is illustrated many times over and over in the examples ... just need a little patience to adapt that code to your needs

JimJim

#6
Hi
Here is some code that I all most have working.  It only will send data one way, is
there anyone that can tell me why it is not sending data back the other way?
(both ways at the same time)
I can get this working with A little bit of help.






const int ledPin =  9;

int val;
int new_val;

int buttonState = 0;
const int buttonPin = 5;


#include <RFM12B.h>
#define NODEID        2  
#define NETWORKID    99  
#define GATEWAYID     1  
#define SERIAL_BAUD  115200
char input = 0;
int interPacketDelay = 1000;
uint8_t KEY[] = "ABCDABCDABCDABCD";

typedef struct  { 
  int power1, power2; 
} 
PayloadTX;
PayloadTX emontx; 

RFM12B radio;

typedef struct {
  int power11, power22;
} 
PayloadRX; 
PayloadRX emonrx;  

void setup()
{
  Serial.begin(SERIAL_BAUD);
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  radio.Encrypt(KEY);
  Serial.println("Transmitting...\n\n");
  pinMode (ledPin, OUTPUT);
}
void loop()

{
  val = analogRead(0);
  new_val = map(val, 0, 1023, 253, 0); 
  buttonState = digitalRead(buttonPin);
  emontx.power1=new_val;
  emontx.power2=buttonState;

  if (Serial.available() > 0) {
    input = Serial.read();
    if (input >= 48 && input <= 57) //[1..9] = {100..900}ms; [0]=1000ms
    {
      interPacketDelay = 100 * (input-48);
      if (interPacketDelay == 0) interPacketDelay = 1000;
      Serial.print("\nChanging delay to ");
      Serial.print(interPacketDelay);
      Serial.println("ms\n");
    }
  }
  radio.Send(GATEWAYID, &emontx, sizeof emontx);
  Serial.print("power1: "); 
  Serial.println(emontx.power1); 
  Serial.print("power2: "); 
  Serial.println(emontx.power2); 
  delay(1000);

  if (radio.ReceiveComplete())
  {
    if (radio.CRCPass())
    {
      emonrx=*(PayloadRX*) radio.Data; 
      Serial.print("power11: "); 
      Serial.println(emonrx.power11); 
      Serial.print("power22: "); 
      Serial.println(emonrx.power22); 

      if (emonrx.power22 == HIGH) {     
        // turn LED on:    
        digitalWrite(ledPin, HIGH);  
      } 
      else {
        // turn LED off:
        digitalWrite(ledPin, LOW); 
        delay(1000);
        }
    }
  }
}






const int ledPin1 =  9;
 
 int val1;
 int new_val1;

 int buttonState1 = 0;
 const int buttonPin1 = 5;

 #include <RFM12B.h>
 #define GATEWAYID     2
 #define NODEID           1  
 #define NETWORKID       99 
 
 #define SERIAL_BAUD 115200
 char input = 0;
 int interPacketDelay = 1000;
 uint8_t KEY[] = "ABCDABCDABCDABCD";
 
 typedef struct  { int power11, power22; } PayloadRX;
 PayloadRX emonrx; 

 RFM12B radio;

 typedef struct {int power1, power2;} 
 PayloadTX; 
 PayloadTX emontx;  

 void setup()
 {
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  radio.Encrypt(KEY);     
  Serial.begin(SERIAL_BAUD);
  Serial.println("Listening...");
  pinMode (ledPin1, OUTPUT);
 }

 void loop()
 {
  val1 = analogRead(0);
  new_val1 = map(val1, 0, 1023, 253, 0); 
  buttonState1 = digitalRead(buttonPin1);
  emonrx.power11=new_val1;
  emonrx.power22=buttonState1;
 
   if (Serial.available() > 0) {
   input = Serial.read();
   if (input >= 48 && input <= 57) //[1..9] = {100..900}ms; [0]=1000ms
    {
     interPacketDelay = 100 * (input-48);
     if (interPacketDelay == 0) interPacketDelay = 1000;
      Serial.print("\nChanging delay to ");
      Serial.print(interPacketDelay);
      Serial.println("ms\n");
    }
   }
   radio.Send(GATEWAYID, &emonrx, sizeof emonrx);
   Serial.print("power11: "); Serial.println(emonrx.power11); 
   Serial.print("power22: "); Serial.println(emonrx.power22); 
   delay(1000);
   
{
  if (radio.ReceiveComplete())
  {
    if (radio.CRCPass())
    {

     emontx=*(PayloadTX*) radio.Data; 
     Serial.print("power1: "); 
     Serial.println(emontx.power1); 
     Serial.print("power2: "); 
     Serial.println(emontx.power2); 
      
if (emontx.power2 == HIGH) {     
        // turn LED on:    
        digitalWrite(ledPin1, HIGH);  
      } 
 else {
        // turn LED off:
        digitalWrite(ledPin1, LOW); 
        delay(1000);

      }
    }
  }
 }
}

Felix

I would start by removing the delay(1000); statements. Those will kill your reception. Basically you're doing nothing most of the time, then for a split second doing everything else and checking if anything was received. Instead you should be checking if something was received most of the time, to avoid losing any received packets. I don't think you'll find any such long delays in any of my examples.

JimJim

Well I got ride of the delay(1000).  There is some thing not right with this line in the code.
radio.Send(GATEWAYID, &emontx, sizeof emontx); If I take it out in one code and leave it
in the other code it work's,  but only sends code one way.  I guess 150 people look at my post
and only one person can help me.  I guess this code is not for me.  There is no easy code to
get started with.  Your code is good but you know what you are doing and most people of
us want to learn,  but the people we try to learn off of don't make it simple .....

life is life.............

JimJim


priority

Quote from: JimJim on December 20, 2013, 12:17:42 AM
I guess 150 people look at my post
and only one person can help me.  I guess this code is not for me.  There is no easy code to
get started with.  Your code is good but you know what you are doing and most people of
us want to learn,  but the people we try to learn off of don't make it simple .....

life is life.............

I see this very differently: 150 views show people are interested in the topic of your thread, but no one sees an obvious cause for your problem.  Having developed products for many years, I can say without hesitation that debugging is an art.  While I have worked with some engineers that seem to have a natural knack for debugging, most of us are continually learning new and different ways of getting our projects working. 

LazyGlen

#11
Quote from: priority on December 20, 2013, 08:16:29 AM
I see this very differently: 150 views show people are interested in the topic of your thread, but no one sees an obvious cause for your problem.  Having developed products for many years, I can say without hesitation that debugging is an art.  While I have worked with some engineers that seem to have a natural knack for debugging, most of us are continually learning new and different ways of getting our projects working.

Likewise. I'm not a coder, but I'm learning as I go. Reading posts about code issues sometimes helps. I have no idea why your code does not work, but some things you have posted make me wonder. There may be a language issue, and that is fine, which may be interfering. Precise statements make all the difference.

in your post:
Quote from: JimJim on December 16, 2013, 08:38:27 PM
Hi
Here is some code that I all most have working.  It only will send data one way, is
there anyone that can tell me why it is not sending data back the other way?
(both ways at the same time)
I can get this working with A little bit of help.
I wonder about the statement "(both ways at the same time)". You do know that the radio can only be sending OR receiving right?

Are your switches de-bounced?

What is connected to Pin 0, and why are you doing an analog read from it, and then mapping it upside down to 253?
  val = analogRead(0);
  new_val = map(val, 0, 1023, 253, 0); 
  buttonState = digitalRead(buttonPin);
  emontx.power1=new_val;
  emontx.power2=buttonState;


Have you successfully had these 2 Moteinos communicating previously in encrypted mode? I'm sure Felix has done this , but until I get things working, I won't add encryption, it's just another thing to wonder about in the code.

As Felix said, sleeping the processor seems like a bad idea, each processor should be constantly polling the radio (and the switch inputs) to see if it has received data or a change in switch state. Get the radios talking, then deal with reducing the power by sleeping if your application requires it.

Start from a known good state and make small changes (and KEEP TRACK OF THEM!) until you get where you are going.

But for goodness sake, don't throw up your hands and complain that someone else isn't debugging your code.

LazyGlen

Felix

LazyGlen - thanks for replying, good pointers, you are spot on.

It's really hard to guess or pinpoint the issue when code is "not working" without having the exact hardware available. I'm often getting support from people that use Moteino in some kind of setup - they write or mod some code, and guess what ... "it doesn't work". So they email me about it hoping I can quick fix the issue.

I think it's obvious how that does not scale at all if I started to do that for everyone right? :)
Thankfully, this forum acts as a buffer for the amount of support I get, and some nice people help in answering questions.
Thanks everyone who is contributing in this small community!

Hardware is hard, there even was an article in Wired about that recently. It's time consuming, has an extreme learning curve, but is very gratifying. Over the years I learned that 2 of the best ways to solve hardware issues are divide&conquer and backtracking. Take baby steps of known working building blocks and move forward putting them together, making bigger working solutions. When something stops working, backtrack and shuffle/rethink etc.