Controlling Arduino connected RF transmitter from internet

Hi,

I'm trying to control a Arduino connected RF transmitter (connected to Pin2 of my Uno) through requests sent by my internet browser. The aim is to capture a string from the internet browser (in this case ?A102) when this is typed as a suffix to the internal IP address into the address bar (so in total the link in the example below would be "192.158.0.155/?A102") and send this string (A102 in this case) to another Arduino with an RF receiver.

The RF receiver sees the string (A102) and checks against the IF statements in its own void loop to see whether the string satisfies any of the IF statements. The string A102 in this case is my instruction for receiver unit with ID "A1" to toggle pin 2.

I think I have successfully managed to compile the sketch for the receiver arduino as follows:

//RF_receiver_unit_identifier_A1

#include <VirtualWire.h>
void setup()
{
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_set_rx_pin(2);
    vw_setup(4000);  // Bits per sec
    //can't use pin1 as it has been set as Arduino uses it as tx pin
    //can't use pin2 as it has been set as receive pin above
    pinMode(3,OUTPUT);
    pinMode(4,OUTPUT);
    pinMode(5,OUTPUT);
    pinMode(6,OUTPUT);
    pinMode(7,OUTPUT);
    pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);
    pinMode(13, OUTPUT);

    vw_rx_start();       // Start the receiver PLL running
}
    void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      
      //can't use pin 01 or pin 02 as used as receive pin for rf receiver
      
      //case for receiver identifier "A1", pin 03
      if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='0')&&(buf[3]=='3')){   
      digitalWrite(3, !digitalRead(3));
      delay(1000);
      }

      //case for receiver identifier "A1", pin 04
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='0')&&(buf[3]=='4')){   
      digitalWrite(4, !digitalRead(4));
      delay(1000);
      }
      


      //case for receiver identifier "A1", pin 05
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='0')&&(buf[3]=='5')){   
      digitalWrite(5, !digitalRead(5));
      delay(1000);
      }
 

      //case for receiver identifier "A1", pin 06
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='0')&&(buf[3]=='6')){   
      digitalWrite(6, !digitalRead(6));
      delay(1000);
      }
    
      
      //case for receiver identifier "A1", pin 07
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='0')&&(buf[3]=='7')){   
      digitalWrite(7, !digitalRead(7));
      delay(1000);
      }
      
      
      //case for receiver identifier "A1", pin 08
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='0')&&(buf[3]=='8')){   
      digitalWrite(8, !digitalRead(8));
      delay(1000);
      }
      
      
      //case for receiver identifier "A1", pin 09
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='0')&&(buf[3]=='9')){   
      digitalWrite(9, !digitalRead(9));
      delay(1000);
      }
      
      
      
      //case for receiver identifier "A1", pin 10
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='1')&&(buf[3]=='0')){   
      digitalWrite(10, !digitalRead(10));
      delay(1000);
      }
      
      
      
      //case for receiver identifier "A1", pin 11
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='1')&&(buf[3]=='1')){   
      digitalWrite(11, !digitalRead(11));
      delay(1000);
      }
      
      
      //case for receiver identifier "A1", pin 12
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='1')&&(buf[3]=='2')){   
      digitalWrite(12, !digitalRead(12));
      delay(1000);
      }
      
      
      //case for receiver identifier "A1", pin 13
      else if((buf[0]=='A')&&(buf[1]=='1')&&(buf[2]=='1')&&(buf[3]=='3')){   
      digitalWrite(13, !digitalRead(13));
      delay(1000);
      }
      
      
      }
      else{
  delay(1000);
    }

}

...but the sketch I've put together for the receiver module as follows has the following compile error:

Working_upto_pin9_withoutpagechange.ino: In function 'void checkForClient()':
Working_upto_pin9_withoutpagechange:76: error: invalid conversion from 'char' to 'const char*'
Working_upto_pin9_withoutpagechange:76: error: initializing argument 1 of 'size_t strlen(const char*)'

#include <Ethernet.h>
#include <SPI.h>
#include <VirtualWire.h>
boolean reading = false;

////////////////////////////////////////////////////////////////////////
//CONFIGURE
////////////////////////////////////////////////////////////////////////
  byte ip[] = { 192, 168, 0, 155 };   //ip address to assign the arduino
  byte gateway[] = { 192, 168, 0, 1 }; //ip address of the gatewa or router

  //Rarly need to change this
  byte subnet[] = { 255, 255, 255, 0 };

  // if need to change the MAC address (Very Rare)
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

  EthernetServer server = EthernetServer(80); //port 80
////////////////////////////////////////////////////////////////////////

void setup(){
  //Pin 13 has LED connected to it, which we will light up during RF transmission

  pinMode(13, OUTPUT);


  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  
  vw_set_ptt_inverted(true); //
  vw_set_tx_pin(2);
  vw_setup(4000);// speed of data transfer Kbps
  
  
  
  
}

void loop(){

  // listen for incoming clients, and process qequest.
  checkForClient();

}

void checkForClient(){

  EthernetClient client = server.available();

  if (client) {

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    boolean sentHeader = false;

    while (client.connected()) {
      if (client.available()) {

        if(!sentHeader){
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          sentHeader = true;
        }

        char c = client.read();

        if(reading && c == ' ') reading = false;
        if(c == '?') reading = true; //found the ?, begin reading the info

        if(reading){
          Serial.print(c);
            
            
            vw_send((uint8_t *)c, strlen(c));
            vw_wait_tx(); // Wait until the whole message is gone
            delay(1000);
            
   

        }

        if (c == '\n' && currentLineIsBlank)  break;

        if (c == '\n') {
          currentLineIsBlank = true;
        }else if (c != '\r') {
          currentLineIsBlank = false;
        }

      }
    }

    delay(1); // give the web browser time to receive the data
    client.stop(); // close the connection:

  } 

}

Is anybody able to tweak my code for me please to fix this issue? I think I'm close. All I'm trying to do on the transmitter side is capture the request from the browser "A102" in this case, and then send to the receiver unit so it can take the appropriate action.

p.s: the reason for the unit identifier "A1" above is so that I can have several "receiver" units with their own unique ID (the others having ID "A2", "A3", and "A4" and so on) but all operating off one "transmitter" unit. All of the units will receive the message "A102", but only the unit with identifier "A1" will take any action. For example, I have written the following sketch for the receiver unit with identifier "A2", which is exactly the same as the sketch for receiver unit with identifier "A1" with the necessary parts changed:

//RF_receiver_unit_identifier_A2

#include <VirtualWire.h>
void setup()
{
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_set_rx_pin(2);
    vw_setup(4000);  // Bits per sec
    //can't use pin1 as it has been set as Arduino uses it as tx pin
    //can't use pin2 as it has been set as receive pin above
    pinMode(3,OUTPUT);
    pinMode(4,OUTPUT);
    pinMode(5,OUTPUT);
    pinMode(6,OUTPUT);
    pinMode(7,OUTPUT);
    pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);
    pinMode(13, OUTPUT);

    vw_rx_start();       // Start the receiver PLL running
}
    void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      
      //can't use pin 01 or pin 02 as used as receive pin for rf receiver
      
      //case for receiver identifier "A2", pin 03
      if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='0')&&(buf[3]=='3')){   
      digitalWrite(3, !digitalRead(3));
      delay(1000);
      }

      //case for receiver identifier "A2", pin 04
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='0')&&(buf[3]=='4')){   
      digitalWrite(4, !digitalRead(4));
      delay(1000);
      }
      


      //case for receiver identifier "A2", pin 05
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='0')&&(buf[3]=='5')){   
      digitalWrite(5, !digitalRead(5));
      delay(1000);
      }
 

      //case for receiver identifier "A2", pin 06
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='0')&&(buf[3]=='6')){   
      digitalWrite(6, !digitalRead(6));
      delay(1000);
      }
    
      
      //case for receiver identifier "A2", pin 07
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='0')&&(buf[3]=='7')){   
      digitalWrite(7, !digitalRead(7));
      delay(1000);
      }
      
      
      //case for receiver identifier "A2", pin 08
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='0')&&(buf[3]=='8')){   
      digitalWrite(8, !digitalRead(8));
      delay(1000);
      }
      
      
      //case for receiver identifier "A2", pin 09
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='0')&&(buf[3]=='9')){   
      digitalWrite(9, !digitalRead(9));
      delay(1000);
      }
      
      
      
      //case for receiver identifier "A2", pin 10
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='1')&&(buf[3]=='0')){   
      digitalWrite(10, !digitalRead(10));
      delay(1000);
      }
      
      
      
      //case for receiver identifier "A2", pin 11
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='1')&&(buf[3]=='1')){   
      digitalWrite(11, !digitalRead(11));
      delay(1000);
      }
      
      
      //case for receiver identifier "A2", pin 12
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='1')&&(buf[3]=='2')){   
      digitalWrite(12, !digitalRead(12));
      delay(1000);
      }
      
      
      //case for receiver identifier "A2", pin 13
      else if((buf[0]=='A')&&(buf[1]=='2')&&(buf[2]=='1')&&(buf[3]=='3')){   
      digitalWrite(13, !digitalRead(13));
      delay(1000);
      }
      
      
      }
      else{
  delay(1000);
    }

}

.....like I say, just need some help getting the compile error in the transmitter sketch (re switching from "char" to "const char* " sorted and then hopefully I'm good to go.

Thanks in advance all :slight_smile:

You're using a single char where a pointer to a char array is expected. Instead of this:

vw_send((uint8_t *)c, strlen(c));

try:

            vw_send(&c, 1);

I do actually want to send an array, or at least a series of characters. Hopefully when you look at the receiver arduino sketch this is what the receiver is looking out for?

On the basis that I do want to send an array/string (or series of characters) and not just one character, I thought of doing the following:

changing:

char c = client.read();

to:

char c = client.readString();

so that it is reading a string.

But then I don' t know how I need to modify the following line to be compatible with this? :

vw_send((uint8_t *)c, strlen(c));

I'm currently getting the following error when I try this:

RF_transmitter_ip155.ino: In function 'void checkForClient()':
RF_transmitter_ip155:67: error: cannot convert 'String' to 'char' in initialization
RF_transmitter_ip155:76: error: invalid conversion from 'char' to 'const char*'
RF_transmitter_ip155:76: error: initializing argument 1 of 'size_t strlen(const char*)'

Also, please note I need to bear in mind that I've written the receiver sketch in the belief that modifying the above to send a array/string will be compatible with that. If not, it would be helpful to know how I need to modify the receiver sketch too?

Thanks :slight_smile:

I should probably reword / clarify what I'm trying to do here.

  • I'm pretty sure (from seeing other people's sketches) that IF I am able to send the "A102" message, the receiver sketch should be able to decode this and act appropriately.

  • So my issue is that I want to be able to somehow shoehorn the string that comes from the browser (Specifically in this case "A102") into a format where it is possible to send it with:

vw_send((uint8_t *)c, strlen(c));

At the moment, it seems that char c = client.read(); is defining a single character (or "char"), whereas vw_send((uint8_t *)c, strlen(c)); is looking for a "const char*" instead.

So in summary, do I not just need to turn the output from client.read into a const char* so that I can send it with vw_send((uint8_t *)c, strlen(c));

????

For background, I used the following tutorial to base my sketch on:

The difference is that in this person's transmitter sketch......:

#include <VirtualWire.h>
char *controller;
void setup() {
  pinMode(13,OUTPUT);
vw_set_ptt_inverted(true); //
vw_set_tx_pin(12);
vw_setup(4000);// speed of data transfer Kbps
}

void loop(){
controller="A1"  ;
vw_send((uint8_t *)controller, strlen(controller));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(13,1);
delay(1000);
digitalWrite(13,0);
delay(1000);
controller="B1"  ;
vw_send((uint8_t *)controller, strlen(controller));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(13,1);
delay(1000);
digitalWrite(13,0);
delay(1000);

}

....the controller value ("A1" or "B1") is supplied in the sketch. In my case, I want to be able to take whatever is sent by the browser (ie through client.read) as my controller value.

Sorry if I'm confusing things here, I'm just trying to provide as much info as possible to make it easier to help me out. Thanks.

I think you need to declare an array of char and accumulate what you're reading in it. Something like

char buf[VW_MAX_MESSAGE_LEN];

When your reading variable is set true, start putting the characters read into c into the array and null terminate it. When reading becomes false, send buf using

buf, strlen(buf));

Thanks Wildbill - have followed your instructions and come up with the following. I'm struggling a bit with constructing the array from the various chars ("c") in a way that doesn't cause compile errors.

Could you take a quick look at the following please, and let me know how I best tweak it to make it work:

#include <Ethernet.h>
#include <SPI.h>
#include <VirtualWire.h>
boolean reading = false;

////////////////////////////////////////////////////////////////////////
//CONFIGURE
////////////////////////////////////////////////////////////////////////
  byte ip[] = { 192, 168, 0, 155 };   //ip address to assign the arduino
  byte gateway[] = { 192, 168, 0, 1 }; //ip address of the gatewa or router

  //Rarly need to change this
  byte subnet[] = { 255, 255, 255, 0 };

  // if need to change the MAC address (Very Rare)
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

  EthernetServer server = EthernetServer(80); //port 80
////////////////////////////////////////////////////////////////////////

void setup(){
  //Pin 13 has LED connected to it, which we will light up during RF transmission

  pinMode(13, OUTPUT);


  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  
  vw_set_ptt_inverted(true); //
  vw_set_tx_pin(2);
  vw_setup(4000);// speed of data transfer Kbps
  
  
  
  
}

void loop(){

  // listen for incoming clients, and process qequest.
  checkForClient();

}

void checkForClient(){

  EthernetClient client = server.available();

  if (client) {

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    boolean sentHeader = false;

    while (client.connected()) {
      if (client.available()) {

        if(!sentHeader){
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          sentHeader = true;
        }

        char buf[VW_MAX_MESSAGE_LEN];         //allocate space for the string
        char c =-1;                            // Where to store the character read
        byte index = 0;                       // Index into array; where to store the character
        
        
        char Comp(char* This) {
  
    {
        if(index < VW_MAX_MESSAGE_LEN) // Where receipt is less than the size of the array
        {
            c = client.read(); // Read a character
            buf[index] = c; // Store it
            index++; // Increment where to write next
            buf[index] = '\0'; // Null terminate the string
        }
    }

    if (strcmp(buf,This)  == 0) {
        for (int i=0;i<VW_MAX_MESSAGE_LEN;i++) {
            buf[i]=0;
        }
        index=0;
        return(0);
    }
    else {
        return(1);
    }
    }

               

        if(reading && c == ' ') reading = false;
        if(c == '?') reading = true; //found the ?, begin reading the info

        if(reading){
          Serial.print(c);
            
           
            vw_send((uint8_t *)buf, strlen(buf));
            vw_wait_tx(); // Wait until the whole message is gone
            delay(1000);
            
   

        }

        if (c == '\n' && currentLineIsBlank)  break;

        if (c == '\n') {
          currentLineIsBlank = true;
        }else if (c != '\r') {
          currentLineIsBlank = false;
        }

      }
    }

    delay(1); // give the web browser time to receive the data
    client.stop(); // close the connection:

  } 

}

A compile error is arising at the line: char Comp(char* This) {

And the compile error at this line is: "a function-definition is not allowed here before '{' token "

[EDIT....extra info]

In summary, I think my sketch can be thought of in three parts:

  1. gather the char c input from the browser - THIS IS WORKING
  2. convert the char c sequence received into an array (buf) - THIS IS WHERE I NEED HELP
  3. Send the array (buf) out as a RF transmission - I BELIEVE THIS BIT WORKS FINE TOO

So I think I just need help with the middle bit?

The compiler is telling you that you have tried to declare one function inside the other here:

        char Comp(char* This) {

You either need to move the declaration outside CheckForClient and call it there or leave the body without the above line.

The problem with leaving the body without the above line (which I would prefer as I'm not that well versed in how to move entire function out and then call it back in again), is that the definition is used again a couple of lines down at:

if (strcmp(buf,This)  == 0) {