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

asked Aug 17, 2019 at 23:49

1 Answer 1

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.

answered Aug 18, 2019 at 5:53
2
  • 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円' Commented Aug 20, 2019 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 Commented Aug 20, 2019 at 7:42

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.