0

I am attempting to use an Arduino Uno WiFi Rev2 board to integrate some lonely data. I will use the NINA WiFi chipset and associated libraries to start a server that will periodically request and receive client information hosted on multiple types of devices that will run concurrently; thus it's pretty much divided in 2 sections: 1.) Manage the client connections and their character arrays 2.) Parsing the information and responding accordingly from a control aspect

This is what I have so far, and what I was just compiling the other day:

#include <stdlib.h>
#include <SPI.h>
#include <WiFiNINA.h>

char ssid[] = "***";                // House -- Network SSID (name)
char pass[] = "***";              // House -- SSID password (WPA2-PSK)

#define MAX_CLIENTS 5
#define MAX_LINE_LEN 50 
char inputs[MAX_CLIENTS][MAX_LINE_LEN] = {0}; // Instantiate 2D array of 
client/received data
int msg_array[] = {0,0};
int net_status = WL_IDLE_STATUS;              // The Wifi radio's status
WiFiServer server(80);           // Create server object on port of WiFi 
                                 // server, which will be used to 
                                 // respond to commands

WiFiClient *clients[MAX_CLIENTS] = {NULL};    // Create client objects 
                                              // limited to size of 
                                              // MAX_CLIENTS


byte mac[] = {0xDE,0xAD,0xBE,0xEF,0xFE,0xED}; // Arduino's physical MAC
byte ip[] = {192,168,9,25};              // IP of this controller 
byte gateway[] = {192,168,0,1};          // Router address (internet)
byte subnet[] = {255,255,0,0};           // Subnet mask

unsigned long wd_Dside, wd_Cside = millis();   // Gather current tstamp
unsigned long wd_Delap, wd_Celap = 0;          // Create an elapsed time 
                                               //counter 


void setup(){

   pinMode(4, OUTPUT);                 // pin selected to control D SIDE
   pinMode(5, OUTPUT);                 // pin selected to control C SIDE

   //enable serial data print 
   Serial.begin(9600); 
   while (!Serial){
       Serial.println("No serial.");
   }

      Serial.println("Serial.begin was initiated."); 


   if (WiFi.status() == WL_NO_SHIELD) {  // check for the WiFi module:
      Serial.println("Wi-Fi: Communication with NINA has failed!");
      // do nothing here
      while (true);
   }

   String fv = WiFi.firmwareVersion();
   if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
      Serial.println("Please upgrade the firmware");
   }

   while (net_status != WL_CONNECTED) {
      Serial.print("Attempting to connect to WPA SSID: ");
      Serial.println(ssid);

      // Connect to WPA/WPA2 network:
      net_status = WiFi.begin(ssid, pass); // Attempt to join this SSID

      // wait 5 seconds for connection:
      delay(5000);

      listNetworks(); 

      server.begin();                      // Start Wi-Fi server
      Serial.print("Server started on ");
      Serial.println(WiFi.localIP()); 
    }
}


void loop() {

    delay(5);

    WiFiClient newClient = server.available(); // Begin listening for  
                                               // client messages 
    if (newClient) {
        Serial.println("New client discovered."); // Could use this as 
                                                  // an ACK/handshake on 
                                                  // client-side host 
        for (int i=0; i<MAX_CLIENTS; i++) {
          if (clients[i] == NULL) {
            clients[i] = new WiFiClient(newClient);
            break;
      }
   }
}

    for (int i=0; i<MAX_CLIENTS; i++){      // Check client for data
      if (clients[i] != NULL && clients[i]->available()){  
         // If the data isn't garbage and the data is available..

        char newChar = clients[i]->read();                            
        // Read the data   

        if (newChar == 'x') {                                         
        // Check for a termination character for separation

        // Now parse with strtok in order to get parameterization
          char delimiters[] = ",";                                    
          char* valIndex;
          valIndex = strtok(inputs[i], delimiters);
          for (int j=0; j < 2; j++){                                  
            // Expand later to largest anticipated character count
            msg_array[j] = atoi(valIndex); 
            Serial.print(msg_array[j]);
            valIndex = strtok(NULL, delimiters);
          }

          switch(msg_array[0]) {          
          // Determine type of message received (Character 0 parsed as 
          // Message Type) 

            case '3':                                                 
            // Examine string for client cmds to turn sides on or off. 
            if(msg_array[1] == '1')                                   
            // Msg type 3, Instruction 1: Turn D side ON
              {
                digitalWrite(4, HIGH);                                
                // Set pin 4 high
                Serial.println("Dside started.");
                wd_Delap = 0;                                         
                // Reset elapsed time watchdog time value for D side. 
                wd_Dside = millis();                                  
                // Last good heartbeat from client device on D side. 
              }
            if(msg_array[1] == '2')                                   
            // Msg type 3, Instruction 2: Turn D side OFF
              {
                digitalWrite(4, LOW);                                 
                // Set pin 4 low
                Serial.println("Dside stopped");
                wd_Delap = 0;                                         
                // Reset elapsed time watchdog time value for D side. 
                wd_Dside = millis();                                  
                // Last good heartbeat from client device on D side. 
              } 
            if(msg_array[1] == '3')                                   
                // Msg type 3, Instruction 3: Turn C side ON
              {
                digitalWrite(5, HIGH);                                
                // Set pin 5 high
                Serial.println("C side started.");
                wd_Celap = 0;                                         
                // Reset elapsed time watchdog time value for C side. 
                wd_Cside = millis();                                  
                // Last good heartbeat from client device on C side. 
              }
            if(msg_array[1] == '4')                                   
                // Msg type 3, Instruction 4: Turn C side OFF
              {
                digitalWrite(5, LOW);                                 
                // Set pin 5 low
                Serial.println("C side stopped.");
                wd_Celap = 0;                                         
                // Reset elapsed time watchdog time value for C side. 
                wd_Cside = millis();                                  
                // Last good heartbeat from client device on C side. 
              }
            break;

            case '6':

                // Examine string for another message type TBD 
            break; 

            default: 
              Serial.println("Default break. Received crap.");
            break;

          }

        inputs[i][0] = '\0';                                          
        // Clear out this array element for the next message
        // clients[i]->stop();                                         
        // By default, kill client session, just wait for new TCP open
        // delete clients[i];                                          
        // Remove client element's data
        // clients[i] = NULL;                                          
        // Reset to NULL 

        }

        else {

           if (strlen(inputs[i]) > MAX_LINE_LEN) {                    
                // First check for size compliance
           Serial.println("Max line length exceeded from client.");
           inputs[i][0] = '0';                                        
                // Clear out this array element for the next message
           }
           else {
           **strcat(inputs[i], newChar);**                                
                // Add character to the received string
           }

          Serial.println(); 
          Serial.println(newChar);
        }
      }

    // Update watchdog timers

    wd_Delap += (millis()-wd_Dside);
    wd_Celap += (millis()-wd_Cside); 

    if (wd_Delap>=60000)
          {
            Serial.print("Elapsed time on watchdog, D side: ");
            Serial.println(wd_Delap);
            Serial.print("Last message received: ");
            Serial.println(wd_Dside);
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println("D side didn't hear from a client in 60s; 
                           defaulting to OFF.");
          } 

    if (wd_Celap>=60000)
          {
            Serial.print("Elapsed time on watchdog, C side: ");
            Serial.println(wd_Celap);
            Serial.print("Last message recieved: ");
            Serial.println(wd_Cside);
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("C side didn't hear from a client in 60s; 
                            defaulting to OFF.");
          } 

   } 
}

I previously had this compiling and running, though with issues that I intedned on iteratively troubleshooting. Now it won't compile because of the following error:

arduino:302:37: error: invalid conversion from 'char' to 'const char*' [-fpermissive]

strcat(inputs[i], newChar); // Add character to the received string

..which I have attempted to bold above in the final else clause. I realize these parameters require pointers, but it seems like some of the other functions like strtok and strlen which ask for pointers as well seem to work okay in my code.

Are there any suggestions or alternatives to strcat() as to how I could make this work? I have mostly stuck with character arrays instead of declaring String objects. I am also obviously pretty rusty at C(++) as I haven't been actively working with it in a while.

Thank you

1

strcat is a function to concatenate strings. It expects a char array as second parameter. You have only a single char newChar to add to your string.

size_t l = strlen(inputs[i]);  
inputs[i][l] = newChar;    
inputs[i][l + 1] = 0;

Note: It would be better to track the length of the inputs then use strlen. strlen iterates over the array until terminating zero.

  • Thank you. I think this will work. Question, is the third line necessary? Wouldn't that just add a character '0' at the end, or are you saying that's the character for termination, which I thought was '\0' – user8585939 Aug 20 at 6:38
  • the next strlen would not work without the terminating zero. ascii code of '\0' is 0. some use NULL, which is 0 too – Juraj Aug 20 at 7:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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