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);
}
}