WIFI client issues

I have C# code which communicates with my arduino. When the Arduino is first started it creates an AP client, my C# code connects to it and passes the credentials for the wifi network , then the arduino creates a normal wifi client. As long as I don't power down the ardiuino it works fine, I can close my C# application and connect to the Arduino but as soon as the Arduino is powered down I cant reconnect to it. I'm sure it's something that Im not starting properly.

#include "WiFiS3.h"
#include "ArduinoBLE.h"
#include <EEPROM.h>
#include <string.h>

#define SSID_ADDRESS 0      // Starting address in EEPROM to store SSID
#define PASS_ADDRESS 51     // Starting address in EEPROM to store password
#define MAX_SSID_LENGTH 50  // Maximum length of SSID
#define MAX_PASS_LENGTH 50  // Maximum length of password

char ssidAP[50] = "SIMRailGolf";  // your network SSID (name)
char passAP[50] = "123456789";
char ssid[50] = "";  // your network SSID (name)
char pass[50] = "";
String Storedssid = "";  // your network SSID (name)
String Storedpass = "";
bool APMode = true;
bool resetting = false;

int status = WL_IDLE_STATUS;
WiFiServer server(80);

const int EnablePin = 2;
const int Direction = 3;
const int StepPin = 4;
const int LeftyPin = 5;
const int RightyPin = 6;
const int ResetPin = 7;
const int WifiPin = 8;

//BLEDevice central;
BLEService smgService("19B10001-E8F2-537E-4F6C-D104768A1214");
BLEStringCharacteristic smgMoveCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1215", BLEWrite | BLENotify, 40);
BLEBooleanCharacteristic smgBusyCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1216", BLERead | BLEWrite | BLENotify);
BLEIntCharacteristic smgTotalPosCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1217", BLERead | BLENotify);
BLEIntCharacteristic smgCurrentPosCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1218", BLERead | BLENotify);
BLEStringCharacteristic smgDebugCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1219", BLERead | BLENotify, 100);

typedef struct funcStruct {
  char funcnameVal[5];
  int dirVal;
  int totalVal;
  int centerVal;
  int speedVal;
  int currentPosVal;
  int accellVal;
} afuncArray;

// Calculate BUF_SIZE based on the size of funcStruct
#define BUF_SIZE (sizeof(afuncArray) + 10)

// Ensure BUF_SIZE is a multiple of the largest member size
#define ALIGN_BUF_SIZE(size) (((size) + 3) & ~3)

// Define BUF_SIZE with proper alignment
#define BUF_SIZE_ALIGNED ALIGN_BUF_SIZE(BUF_SIZE)

afuncArray incomingArray;
afuncArray* incomingArrayPtr = &incomingArray;
byte incomingStr[100];
char incomingBuffer[BUF_SIZE];
char* strtokIndx;
int currentPos;
char functionName[5];
int dir;
int totalSteps;
int isWifi;
WiFiClient client;

void setup() {
  //delay(1000);
  pinMode(LeftyPin, INPUT_PULLUP);
  pinMode(RightyPin, INPUT_PULLUP);
  pinMode(Direction, OUTPUT);
  pinMode(StepPin, OUTPUT);
  pinMode(EnablePin, OUTPUT);
  pinMode(WifiPin, INPUT_PULLUP);
  pinMode(ResetPin, INPUT_PULLUP);
  digitalWrite(EnablePin, LOW);
  //delay(1000);


  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }
  isWifi = digitalRead(WifiPin);
  delay(1000);
  int resetval = digitalRead(ResetPin);
  delay(1000);
  //Serial.println(ResetPin);

  if ((resetval == 0)) {
    Serial.println("reset");
    resetting = true;
    ResetEEprom();
  }

  if (isWifi == 0) {
    Serial.println("Wifi");
    Storedssid = readStringFromEEPROM(SSID_ADDRESS);
    Storedpass = readStringFromEEPROM(PASS_ADDRESS);
    Serial.println(Storedssid);
    Serial.println(Storedpass);

    if ((Storedssid == "") & (Storedpass == "")) {

      // by default the local IP address will be 192.168.4.1
      // you can override it with the following:
      WiFi.config(IPAddress(192, 48, 56, 2));
      WiFi.setHostname("SIMRailGolf");
      // print the network name (SSID);
      // Create open network. Change this line if you want to create an WEP network:
      status = WiFi.beginAP(ssidAP, passAP);
      if (status != WL_AP_LISTENING) {
        // don't continue
        while (true)
          ;
      }
      // wait 10 seconds for connection:
      delay(2000);

      // start the web server on port 80
      server.begin();

      // compare the previous status to the current status
      if (status != WiFi.status()) {
        // it has changed update the variable
        status = WiFi.status();

        if (status == WL_AP_CONNECTED) {
        } else {
        }
      }
      while (!server.available()) {
        delay(200);
      }

      WiFiClient client = server.available();

      if (client) {  // if you get a client,
        String request = "";
        while (client.connected()) {  // loop while the client's connected
          delayMicroseconds(10);      // This is required for the Arduino Nano RP2040 Connect - otherwise it will loop so fast that SPI will never be served.
          if (client.available()) {
            request += client.readString();
            if (request.indexOf("\r\n\r\n") != -1) {
              break;
            }
          }
        }
        // Respond to the request
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/plain");
        client.println();
        client.println("Success!");

        delay(100);
        // Find the position of the comma
        int equalsIndex = request.indexOf('=');
        int ampersandIndex = request.indexOf('&');
        int strLength = request.length();
        if (strLength > 0) {
          // Extract the substring for pass and ssid
          request.substring(equalsIndex + 1, ampersandIndex).toCharArray(pass, sizeof(pass));
          request.substring(ampersandIndex + strlen("&ssid=")).toCharArray(ssid, sizeof(ssid));
          writeStringToEEPROM(SSID_ADDRESS, ssid);
          writeStringToEEPROM(PASS_ADDRESS, pass);
        }
      }
      client.stop();
      WiFi.disconnect();
      WiFi.end();
      server.end();
    } else {
      Storedssid.toCharArray(ssid, MAX_SSID_LENGTH);
      Storedpass.toCharArray(pass, MAX_PASS_LENGTH);
    }

    WiFi.setHostname("SIMRailGolf");
    //Serial.println(ssid);
    //Serial.println(pass);

    status = WiFi.begin(ssid, pass);

    while (status != WL_CONNECTED) {
      delay(1000);
    }
    //IPAddress ip = WiFi.localIP();
    //Serial.print("IP Address: ");
    //Serial.println(ip);
    //server.begin();
  } else {
    if (!BLE.begin()) {
      while (1)
        ;
    }
    Serial.println("BT");

    BLE.setLocalName("SIMRailConnector");
    BLE.setDeviceName("SIMRailConnector");
    BLE.setAdvertisedService(smgService);

    smgService.addCharacteristic(smgMoveCharacteristic);
    smgService.addCharacteristic(smgBusyCharacteristic);
    smgService.addCharacteristic(smgTotalPosCharacteristic);
    smgService.addCharacteristic(smgCurrentPosCharacteristic);
    smgService.addCharacteristic(smgDebugCharacteristic);
    BLE.addService(smgService);
    // assign event handlers for characteristic
    smgMoveCharacteristic.setEventHandler(BLEWritten, smgMoveCharacteristicWritten);
    //  smgBusyCharacteristic.setEventHandler(BLEWritten, smgBusyCharacteristicWritten);
    BLE.advertise();
    smgBusyCharacteristic.writeValue(false);
    smgBusyCharacteristic.broadcast();
  }
}

void loop() {
  isWifi = digitalRead(WifiPin);
  if (isWifi == 0) {
    if (status != WL_CONNECTED) {
      createConnection();
    }
    client = server.available();  // listen for incoming clients
    while (client.connected()) {
      if (client.available()) {
        String c = client.readStringUntil('\r');
        delay(1000);
        readWIFICommand(c);
        delay(100);
      }
    }
  } else {
    BLE.poll();
  }
}

void smgMoveCharacteristicWritten(BLEDevice central, BLECharacteristic characteristic) {
  // central wrote new value to characteristic, update LED
  smgBusyCharacteristic.writeValue(true);
  smgBusyCharacteristic.broadcast();
  delayMicroseconds(100);

  int bytesRead = smgMoveCharacteristic.readValue((uint8_t*)incomingBuffer, BUF_SIZE);
  delayMicroseconds(1000);


  // Convert the received byte array to a string
  incomingBuffer[bytesRead] = '\0';  // Ensure null termination

  // Parse the received string
  strtokIndx = strtok(incomingBuffer, ",");
  if (strtokIndx != NULL) {
    strncpy(incomingArray.funcnameVal, strtokIndx, sizeof(incomingArray.funcnameVal) - 1);
    incomingArrayPtr->funcnameVal[sizeof(incomingArray.funcnameVal) - 1] = '\0';  // Ensure null termination
    incomingArrayPtr->dirVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->totalVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->centerVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->speedVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->currentPosVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->accellVal = strtoul(strtok(NULL, ","), NULL, 10);
  }
  digitalWrite(EnablePin, HIGH);
  delayMicroseconds(1000);
  MoveToStep(&incomingArray);
  delayMicroseconds(1000);

  digitalWrite(EnablePin, LOW);
  smgBusyCharacteristic.writeValue(false);
  smgBusyCharacteristic.broadcast();
}

void readWIFICommand(String IncommingCommand) {

  IncommingCommand.toCharArray(incomingBuffer, sizeof(incomingBuffer));

  strtokIndx = strtok(incomingBuffer, ",");
  if (strtokIndx != NULL) {
    strncpy(incomingArray.funcnameVal, strtokIndx, sizeof(incomingArray.funcnameVal) - 1);
    incomingArrayPtr->funcnameVal[sizeof(incomingArray.funcnameVal) - 1] = '\0';  // Ensure null termination
    incomingArrayPtr->dirVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->totalVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->centerVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->speedVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->currentPosVal = strtoul(strtok(NULL, ","), NULL, 10);
    incomingArrayPtr->accellVal = strtoul(strtok(NULL, ","), NULL, 10);
  }
  if (incomingArrayPtr->funcnameVal == "exit") {
    strcpy(incomingArrayPtr->funcnameVal, "move");
  }
  digitalWrite(EnablePin, HIGH);
  delayMicroseconds(1000);
  MoveToStep(&incomingArray);
  delayMicroseconds(1000);
  digitalWrite(EnablePin, LOW);
  if (incomingArrayPtr->funcnameVal == "exit") {
    delayMicroseconds(1000);
    client.stop();
    WiFi.disconnect();
    WiFi.end();
    server.end();
  }
}


void MoveToStep(afuncArray* command) {
  //char functionName[5];
  //int dir;
  int Speed;
  int CenterPos;
  int SpeedUp = 1;
  int SpeedDif;
  int StepsToFullSpeed;
  int StepPos;
  int motorSpeed = 0;
  int totalSteps = 0;
  // int currentPos = 0;
  int startStopSpeed = 800;
  int accelaration = 15;
  int buttonStateLeft = 0;
  int buttonStateRight = 0;
  delayMicroseconds(800);
  strcpy(functionName, command->funcnameVal);
  dir = command->dirVal;
  StepPos = command->totalVal;
  CenterPos = command->centerVal;
  Speed = command->speedVal;
  currentPos = command->currentPosVal;
  accelaration = command->accellVal - 5;
  motorSpeed = startStopSpeed;
  SpeedDif = startStopSpeed - Speed;
  if (SpeedDif > 0) {
    StepsToFullSpeed = SpeedDif * accelaration;
  } else {
    StepsToFullSpeed = accelaration;
  }

  if (dir == 0) {
    if ((currentPos - StepPos) < (StepsToFullSpeed * 2)) {
      StepsToFullSpeed = ((currentPos - StepPos) / 2);
    }
    digitalWrite(Direction, LOW);
    buttonStateRight = digitalRead(RightyPin);
    delayMicroseconds(1000);
    do {
      do {
        while ((buttonStateRight == 1)) {
          totalSteps = ++totalSteps;
          if (SpeedUp == 1) {
            if ((motorSpeed > Speed) && (StepsToFullSpeed < (currentPos - StepPos))) {
              if ((currentPos % accelaration) == 0) {
                motorSpeed = --motorSpeed;
              }
            } else if (StepsToFullSpeed > (currentPos - StepPos)) {
              SpeedUp = 0;
            }
          } else {
            if (motorSpeed < startStopSpeed) {
              if ((currentPos % accelaration) == 0) {
                motorSpeed = ++motorSpeed;
              }
            }
          }
          digitalWrite(StepPin, LOW);
          delayMicroseconds(motorSpeed);
          digitalWrite(StepPin, HIGH);
          delayMicroseconds(motorSpeed);
          currentPos = --currentPos;
          buttonStateRight = digitalRead(RightyPin);
        }
        delayMicroseconds(100);
        buttonStateRight = digitalRead(RightyPin);
      } while (buttonStateRight == 1);
      delayMicroseconds(100);
      buttonStateRight = digitalRead(RightyPin);
    } while (buttonStateRight == 1);
    currentPos = 1;
  } else if (dir == 1) {
    if ((StepPos - currentPos) < (StepsToFullSpeed * 2)) {
      StepsToFullSpeed = ((StepPos - currentPos) / 2);
    }
    digitalWrite(Direction, HIGH);
    buttonStateLeft = digitalRead(LeftyPin);
    delayMicroseconds(1000);
    do {
      do {
        while ((buttonStateLeft == 1)) {
          if (SpeedUp == 1) {
            if ((motorSpeed > Speed) && (StepsToFullSpeed < (StepPos - currentPos))) {
              if ((currentPos % accelaration) == 0) {
                motorSpeed = --motorSpeed;
              }
            } else if (StepsToFullSpeed > (StepPos - currentPos)) {
              SpeedUp = 0;
            }
          } else {
            if (motorSpeed < startStopSpeed) {
              if ((currentPos % accelaration) == 0) {
                motorSpeed = ++motorSpeed;
              }
            }
          }
          digitalWrite(StepPin, LOW);
          delayMicroseconds(motorSpeed);
          digitalWrite(StepPin, HIGH);
          delayMicroseconds(motorSpeed);
          currentPos = ++currentPos;
          buttonStateLeft = digitalRead(LeftyPin);
        }
        delayMicroseconds(100);
        buttonStateLeft = digitalRead(LeftyPin);
      } while (buttonStateLeft == 1);
      delayMicroseconds(100);
      buttonStateLeft = digitalRead(LeftyPin);
    } while (buttonStateLeft == 1);
  } else if (dir == 2) {
    if (currentPos < CenterPos) {
      StepsToFullSpeed = ((CenterPos - currentPos) / 2);
      digitalWrite(Direction, HIGH);
      delayMicroseconds(1000);
      while (currentPos < CenterPos) {
        if (SpeedUp == 1) {
          if (StepsToFullSpeed < (CenterPos - currentPos)) {
            if ((currentPos % accelaration) == 0) {
              motorSpeed = --motorSpeed;
            }
          }
          if (StepsToFullSpeed > (CenterPos - currentPos)) {
            SpeedUp = 0;
          }
        } else {
          if ((currentPos % accelaration) == 0) {
            motorSpeed = ++motorSpeed;
          }
        }
        digitalWrite(StepPin, LOW);
        delayMicroseconds(motorSpeed);
        digitalWrite(StepPin, HIGH);
        delayMicroseconds(motorSpeed);
        currentPos = ++currentPos;
      }
    } else {
      StepsToFullSpeed = ((currentPos - CenterPos) / 2);
      digitalWrite(Direction, LOW);
      delayMicroseconds(1000);
      while (currentPos > CenterPos) {
        if (SpeedUp == 1) {
          if (StepsToFullSpeed < (currentPos - CenterPos)) {
            if ((currentPos % accelaration) == 0) {
              motorSpeed = --motorSpeed;
            }
          }
          if (StepsToFullSpeed > (currentPos - CenterPos)) {
            SpeedUp = 0;
          }
        } else {
          if ((currentPos % accelaration) == 0) {
            motorSpeed = ++motorSpeed;
          }
        }
        digitalWrite(StepPin, LOW);
        delayMicroseconds(motorSpeed);
        digitalWrite(StepPin, HIGH);
        delayMicroseconds(motorSpeed);
        currentPos = --currentPos;
      }
    }
  }
  isWifi = digitalRead(WifiPin);
  if (isWifi == 1) {
    smgCurrentPosCharacteristic.writeValue(currentPos);
    smgCurrentPosCharacteristic.broadcast();
    delayMicroseconds(10000);

    if ((strcmp(functionName, "cal") == 0) && (incomingArrayPtr->dirVal == 0)) {
      smgDebugCharacteristic.writeValue("entered" + String(totalSteps));
      smgDebugCharacteristic.broadcast();
      delayMicroseconds(10000);
      smgTotalPosCharacteristic.writeValue(totalSteps);
      smgTotalPosCharacteristic.broadcast();
      delayMicroseconds(10000);
    }
  } else {
    if ((strcmp(functionName, "cal") == 0) && (incomingArrayPtr->dirVal == 0)) {
      client.print(currentPos);
      client.print(",");
      client.println(totalSteps);
      delayMicroseconds(10000);
    } else {
      client.println(currentPos);
      delayMicroseconds(10000);
    }
  }
}
void writeStringToEEPROM(int addr, const char* data) {
  // Write string length to EEPROM
  int len = strlen(data);
  EEPROM.write(addr, len);

  // Write string characters to EEPROM
  for (int i = 0; i < len; i++) {
    EEPROM.write(addr + 1 + i, data[i]);
  }
}

String readStringFromEEPROM(int addr) {
  // Read string length from EEPROM
  int len = EEPROM.read(addr);

  // Read string characters from EEPROM
  String data = "";
  for (int i = 0; i < len; i++) {
    data += char(EEPROM.read(addr + 1 + i));
  }
  return data;
}
void ResetEEprom() {
  for (int i = 0; i < EEPROM.length(); i++) {
    EEPROM.write(i, 0);
  }
  //Serial.println("EPROM Reset");
}
void createConnection() {
  // This new line is required to disconnect the previous connection otherwise
  // it will try to use the old connection and never reconnect if the connection fails
  status = WiFi.disconnect();

  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();  // start the web server on port 80
  while (!server.available()) {
    delay(200);
  }
}

Perhaps I am misunderstanding, but if you power down the Arduino it will restart exactly the same as the first time. That means your C# code needs to connect to the AP on the Arduino etc.

The second time it starts up it with skip the AP part because the credentials are stored in the aduino memory
```
Storedssid = readStringFromEEPROM(SSID_ADDRESS);
Storedpass = readStringFromEEPROM(PASS_ADDRESS);
Serial.println(Storedssid);
Serial.println(Storedpass);

if ((Storedssid == "") & (Storedpass == "")) {

I am a little rusty at 82, but shouldn't that be a logical and with &&

Good catch, thanks.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.