No, it does not contain while(!Serial).
Here's the full code:
#include <ArduinoJson.h>
#include <Wire.h>
#include <PCA9685.h>
#include <EEPROM.h>
#define SWITCH 6
PCA9685 driver = PCA9685(0x40, PCA9685_MODE_N_DRIVER, 1500);
char rxBuf[512]; // This is important
size_t rxInd = 0;
bool switchState, state;
bool isOnline = false;
long nextOnlineTest;
int brightness;
int loadRx() { // This function is important
int count = 0;
long start = millis();
while(millis() < start + 50) {
while(Serial1.available()) {
if(rxInd == 511) {
return count;
}
char c = Serial1.read();
rxBuf[rxInd] = c;
rxInd++;
rxBuf[rxInd] = 0;
count++;
start = millis();
}
}
return count;
}
void clearRx() {
rxInd = 0;
*rxBuf = 0;
}
void flushRx() {
while(Serial1.available()) Serial1.read();
}
void LEDUpdate() {
showAll(state ? brightness : 0);
}
void showAll(int brightness) {
for(int i = 0; i < 13; i++) {
driver.getPin(i).setValueAndWrite(brightness);
}
}
void setup() {
// put your setup code here, to run once:
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
Serial1.begin(115200);
pinMode(SWITCH, INPUT_PULLUP);
Wire.begin();
driver.setup();
delay(10);
while(!strstr(rxBuf, "OK")) {
Serial1.println("AT");
delay(20);
loadRx();
}
digitalWrite(LED_BUILTIN, HIGH);
//Serial1.println("ATE0");
nextOnlineTest = 0;
clearRx();
flushRx();
Serial.println("ESP READY");
switchState = digitalRead(SWITCH);
state = switchState;
brightness = (EEPROM.read(1)<<8)+EEPROM.read(2);
Serial.print("Brightness: ");
Serial.println(brightness);
LEDUpdate();
}
void strapd(char* str, char c) {
size_t len = strlen(str);
str[len] = c;
str[len+1] = 0;
}
void processRxBuf() {
Serial.print("Buffer: ");
Serial.println(strlen(rxBuf));
Serial.println("---------------------");
Serial.println(rxBuf);
Serial.println("-------------------------");
char* ptr = rxBuf;
while(*ptr) {
if(strncmp(ptr, "+IPD", 4) == 0) {
ptr += 5;
char lenStr[4];
lenStr[0] = 0;
while(*ptr != ':') {
strapd(lenStr, *ptr);
ptr++;
}
ptr++;
int len = atoi(lenStr);
char message[len + 1];
message[0] = 0;
strncpy(message, ptr, len);
message[len] = 0;
processMessage(message);
}
ptr++;
}
clearRx();
}
void executeMessage(char* sender, char* content) {
if(strcmp(content, "off") == 0) {
state = false;
LEDUpdate();
sendToHub("BROADCAST", "STATE:off");
} else if(strcmp(content, "on") == 0) {
state = true;
LEDUpdate();
sendToHub("BROADCAST", "STATE:on");
} else if(strncmp(content, "brightness ", 11) == 0) {
brightness = atoi(content + 11);
EEPROM.write(1, brightness >> 8);
EEPROM.write(2, brightness & 0xFF);
state = true;
LEDUpdate();
sendToHub("BROADCAST", "STATE:on");
} else if(strcmp(content, "getstate") == 0) {
char buf[16];
sprintf(buf, "STATE:%s", state ? "on" : "off");
sendToHub(sender, buf);
} else if(strcmp(content, "getbrightness") == 0) {
char buf[24];
sprintf(buf, "BRIGHTNESS:%d", brightness);
sendToHub(sender, buf);
}
}
void processMessage(char* message) {
Serial.print("Received Message: ");
Serial.println(message);
DynamicJsonDocument doc(512);
DeserializationError err = deserializeJson(doc, message);
if(err) {
Serial.print("Json Deserialization Error: ");
Serial.println(err.f_str());
return;
}
const char* method = doc["method"];
if(strcmp(method, "Hub") != 0) return;
const char* sender = doc["sender"];
const char* content = doc["content"];
executeMessage(sender, content);
}
void sendToHub(char* target, char* content) {
char buf[256];
sprintf(buf, "{\"method\":\"Hub\",\"target\":\"%s\",\"content\":\"%s\"}", target, content);
sendUdp(buf);
}
void sendUdp(char* message) {
Serial.print("Sending: ");
Serial.print(message);
char buf[80];
sprintf(buf, "AT+CIPSEND=%d", strlen(message));
Serial1.println(buf);
delay(10);
Serial1.println(message);
}
void loop() {
// put your main code here, to run repeatedly:
if(!isOnline && millis() >= nextOnlineTest) {
nextOnlineTest = millis() + 500;
Serial1.println("AT+CIPSTA?");
delay(10);
loadRx();
if(strstr(rxBuf, "192.168.")) {
isOnline = true;
Serial1.println("AT+CIPSTART=\"UDP\",\"192.168.0.101\",2444,2444");
delay(10);
char buf[16];
sprintf(buf, "STATE:%s", state ? "on" : "off");
sendToHub("BROADCAST", buf);
}
clearRx();
}
while(Serial.available()) Serial1.write(Serial.read());
int i = loadRx();
if(i) processRxBuf();
if(digitalRead(SWITCH) != switchState) {
switchState = digitalRead(SWITCH);
state = switchState;
LEDUpdate();
sendToHub("BROADCAST", state ? "STATE:on" : "STATE:off");
}
}
The important Part is in setup():
while(!strstr(rxBuf, "OK")) {
Serial1.println("AT");
delay(20);
loadRx();
}
The Arduino repeatedly sends "AT" over Serial1.
The ESP should then respond with "OK".
It reads all incoming data in the loadRx() function (defined at the top of the file).
When the "OK" is received, the Built-in LED turns on.
The LED turns on and everything works fine, when a USB Connection is present.
However this does not work without a USB Connection. The LED does not turn on, and it gets stuck in this loop.
Everything after this code is unimportant here, because it never gets executed anyways, so you can ignore all functions except setup() and loadRx().