0

I am a beginner in Arduino programming so that program is also little bit lengthy sorry for inconvenience. I have make a program for wire less controlling of a servo motor and LED(7 Nos.) using ARDUINO UNO, Funduino Joy stick shield V1.A and NRF24L01.First i have prepare the program (using Array) only for controlling the LEDs and its become success as that LEDs working as per program.Than i added Servo motor also in circuit and make some changes in existing LED program. Unfortunately the result is erratic out put.joy stick input signal interrupting the led signal and some time servo motor respond led input .Transmitting code and Reciever code given below.

I came to know that this problem will solve using "struct" command in existing program . Please help me to modify the program with "struct".Because i have no thorough knowledge in C,C++

TRANSMITTER

    #include <SPI.h>
    #include <RF24.h>
    #include <nRF24L01.h

>



#define xAxis A0   
RF24 radio(9,10);
const uint64_t pipe = 0xF0F0F0F0D2L;

int msg[1];
int buttonPin1 = 2;
int buttonPin2 = 3;
int buttonPin3 = 4;
int buttonPin4 = 5;
int buttonPin5 = 6;
int buttonPin6 = 7;
int buttonPin7 = 8;
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;
int buttonState6 = 0;
int buttonState7 = 0;


void setup(void)
{
  radio.begin();
  radio.openWritingPipe(pipe);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);
  pinMode(buttonPin6, INPUT_PULLUP);
  pinMode(buttonPin7, INPUT_PULLUP);
}

void loop(void)
{
  int potValue = analogRead(A0);                              //  INPUT FOR SERVO MOTOR
  int angleValue = map(potValue, 0, 1023, 0, 180); // INPUT FOR SERVO MOTOR
  radio.write(&angleValue, sizeof(angleValue));         // INPUT FOR SERVO MOTOR

  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  buttonState4 = digitalRead(buttonPin4);
  buttonState5 = digitalRead(buttonPin5);
  buttonState6 = digitalRead(buttonPin6);
  buttonState7 = digitalRead(buttonPin7);


 if (buttonState1 == LOW){
    msg[0] = 111;
    radio.write(msg, 1);               // INPUT FOR LED1
   }
 if (buttonState2 == LOW){ 
    msg[0] = 222;
    radio.write(msg, 1);               // INPUT FOR LED2
   }
 if (buttonState3 == LOW){
    msg[0] = 212;
    radio.write(msg, 1);               // INPUT FOR LED3
   }  
 if (buttonState4 == LOW){
    msg[0] = 216;
    radio.write(msg, 1);                 // INPUT FOR LED4
   }
 if (buttonState5 == LOW){
    msg[0] = 218;
    radio.write(msg, 1);                // INPUT FOR LED5
   }
 if (buttonState6 == LOW){
    msg[0] = 220;
    radio.write(msg, 1);                 // INPUT FOR LED6
   }
    if (buttonState7 == LOW){
    msg[0] = 224;
    radio.write(msg, 1);
   }                                              // INPUT FOR LED7

  }

RECIEVER

 #include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>  
#include <Servo.h>  // SERVO LIBRARY INCLUDED

Servo myServo; 
RF24 radio(9,10);
const uint64_t pipe = 0xF0F0F0F0D2L;

int led1 = 2;
int led2 = A2;
int led3 = 4;
int led4 = 5;
int led5 = 6;
int led6 = 7;
int led7 = 8;
int msg[1];
int angleValue ;

void setup(void)
{
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1, pipe);
  radio.startListening();
  myServo.attach(3);                  // SERVO CONNECTED TO PIN 3
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
}
void loop(void)
{
   // Receiving code for LED 1 TO LED 7

  if(radio.available()){
    bool done = false;
    while (!done) {
    done = radio.read(msg, 1);
    Serial.println(msg[0]);

    if (msg[0] == 111) {
      digitalWrite(led1, HIGH);
      digitalWrite(led7, LOW);
      }
    if(msg[0] == 222){
        digitalWrite(led1, LOW);
        digitalWrite(led2, HIGH);
        digitalWrite(led7, LOW);
        }
     else if (msg[0] == 111){
          digitalWrite(led2, LOW);
        }
     else if(msg[0] == 212){

          digitalWrite(led3, HIGH);
        }
    else if(msg[0] == 216){
          digitalWrite(led4, HIGH);
        }
    else if(msg[0] == 218){
          digitalWrite(led5, HIGH);
        }
    else if(msg[0] == 220){
          digitalWrite(led6, HIGH);
        }
    else if(msg[0] == 224){
          digitalWrite(led7, HIGH);
          digitalWrite(led1, LOW);
          digitalWrite(led2, LOW);
        delay(10);
        }
      }
   }

//Recieving code for servo motor

    if(radio.available()){           
      bool done = false;             
      while (!done) {
      done = radio.read(&angleValue,sizeof (angleValue) );
      myServo.write(angleValue);}
      delay(10);
     }
                  //Receiving code for LEDs
      else {   
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);

      }
 }

I have tried to make a program using "struct" for 6 button state and one angle input signal to control using 6 LEDs and one Servo and its working fine(Program mentioned below.) But problem is that when i add two more input signal that time output become erratic and output is not getting as per program.Please help to modify the program. transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#define CE_PIN   9
#define CSN_PIN 10
const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN);
int upbut = 2;
int rightbut = 3;
int downbut = 4;
int leftbut = 5;
int nuetral = 6;
int starte = 7;
int stope = 8;
struct data {
    uint8_t leds;
    uint8_t angle;
};
struct data packet;
void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);
  pinMode(upbut,INPUT_PULLUP);
  digitalWrite(upbut,LOW);
  pinMode(rightbut,INPUT_PULLUP);
  digitalWrite(rightbut,LOW);
   pinMode(downbut,INPUT_PULLUP);
  digitalWrite(downbut,LOW);
  pinMode(leftbut,INPUT_PULLUP);
  digitalWrite(leftbut,LOW);
  pinMode(nuetral,INPUT_PULLUP);
  digitalWrite(nuetral,LOW);
  pinMode(starte,INPUT_PULLUP);
  digitalWrite(starte,LOW);
  pinMode(stope,INPUT_PULLUP);
  digitalWrite(stope,LOW);
  //end pinMode and digitalWrite
}//--(end setup )---
void loop(){
int potValue = analogRead(A0);
packet.angle = map(potValue, 0, 1023, 0, 180);

packet.leds = 0;
packet.leds = digitalRead(upbut) ? 0x00 : 0x01;
packet.leds |= digitalRead(rightbut) ? 0x00 : 0x02;
packet.leds |= digitalRead(downbut) ? 0x00 : 0x04;
packet.leds |= digitalRead(leftbut) ? 0x00 : 0x08;
packet.leds |= digitalRead(nuetral) ? 0x00 : 0x10;
packet.leds |= digitalRead(starte) ? 0x00 : 0x20;
/*packet.leds |= digitalRead(starte) ? 0x00 : 0x30;*/

radio.write((uint8_t *)&packet, sizeof(struct data));
}

receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

#include <Servo.h>
#define CE_PIN 6
#define CSN_PIN 7
const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN); 
const int servo1 = 9;
int servoVal;
Servo myservo1;
struct data {
    uint8_t leds;
    uint8_t angle;
};
struct data packet;
int led1 = 2; // digital out put
int led2 = 3; // digital out put
int led3 = 4; // digital out put
int led4 = 5; // digital out put
int led5 = 8; // digital out put
int led6 = A0; // digital out put
int led7 = A1; // digital out put
void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  myservo1.attach(servo1); // attaches the servo1 /analog output

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  Serial.println("Nrf24L01 Receiver Starting");
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();;
}                             //--(end setup )---

void loop(){

if (radio.available()) {
    radio.read((uint8_t *)&packet, sizeof(struct data));
    myservo1.write(packet.angle);
   if (packet.leds ==0x01){
    digitalWrite(led1, packet.leds & 0x01);
    digitalWrite(led2, packet.leds & 0x00);
    digitalWrite(led6, packet.leds & 0x00);
    }
   else if (packet.leds ==0x02){
    digitalWrite(led2, packet.leds & 0x02);
    digitalWrite(led1, packet.leds & 0x00);
    digitalWrite(led6, packet.leds & 0x00);
    }
    else if (packet.leds ==0x20){
    digitalWrite(led6, packet.leds & 0x20);
    digitalWrite(led1, packet.leds & 0x00);
    digitalWrite(led2, packet.leds & 0x00);
    }
    digitalWrite(led3, packet.leds & 0x04);
    digitalWrite(led4, packet.leds & 0x08);
    digitalWrite(led5, packet.leds & 0x10);

   /*digitalWrite(led7, packet.leds & 0x30);*/
}
}
2
  • You are sending two bytes, which each carry different information (LED and servo values), but you don't have any method to tell them apart. Think about what happens, when one byte is lost on the transmission. Everything will get out of step. Maybe you should only send complete messages with a delimiter, that marks the end of a package. Inside this package you can use the byte positions. Also maybe you need some kind of error detection/correction.
    – chrisl
    Commented Apr 30, 2018 at 10:11
  • No need for delimiters with the nRF systems - they send discrete packets.
    – Majenko
    Commented Apr 30, 2018 at 12:30

1 Answer 1

1

Your whole method is completely wrong.

Instead of sending bytes with some unknown meaning at random times you need a far more structured approach to sending your data.

You need to either:

  • Send the meaning of the byte(s) along with the byte(s), or
  • Send all the information every time at pre-defined periods.

Of the two options I'd favour the latter, using a struct:

struct data {
    uint8_t leds;
    uint8_t angle;
};

And then:

struct data packet;

int potValue = analogRead(A0);
packet.angle = map(potValue, 0, 1023, 0, 180);

packet.leds = 0;
packet.led |= digitalRead(buttonPin1) ? 0x00 : 0x01;
packet.led |= digitalRead(buttonPin2) ? 0x00 : 0x02;
packet.led |= digitalRead(buttonPin3) ? 0x00 : 0x04;
packet.led |= digitalRead(buttonPin4) ? 0x00 : 0x08;
packet.led |= digitalRead(buttonPin5) ? 0x00 : 0x10;
packet.led |= digitalRead(buttonPin6) ? 0x00 : 0x20;

radio.write((uint8_t *)&packet, sizeof(struct data));

Then when reading you do the exact opposite:

struct data packet;

if (radio.available()) {
    radio.read((uint8_t *)&packet, sizeof(struct data));
    myServo.write(packet.angle);
    digitalWrite(led1, packet.leds & 0x01);
    digitalWrite(led2, packet.leds & 0x02);
    digitalWrite(led3, packet.leds & 0x04);
    digitalWrite(led4, packet.leds & 0x08);
    digitalWrite(led5, packet.leds & 0x10);
    digitalWrite(led6, packet.leds & 0x20);
}

The struct combines a number of variables together into one single block of data giving you easy access by name to the different portions. One, the leds variable, is then used as a bitmap of whether each LED is on (1) or off (0). That way you can send the current state of up to 8 LEDs in just a single byte. If you want to expand that to send different combinations of LEDs then just change which bits of the byte are set.

If you want to "toggle" the LEDs then it will be necessary to keep a record at the sender of the states and send that instead of the raw button data.

1
  • Up to 6 leds and one angle input this working fine.But i have add one led and angle input more that time output become erratic.#include
    – SREEKe
    Commented May 1, 2018 at 17:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.