Currently working on a project which involves esp8266-01 and arduino uno. All communication is done via AT commands. Esp firmware updated to the latest available 1.6.1
Whole code is working good in arduino i.e. using serial monitor esp not attached.
Using 2 pcs same time one attached to arduino the other one to esp and me phisically passthrough-ing all data between them everythibg works as expected.
But when they both are attached togather via tx and rx pins then something is going wrong which i cant debug. My question is are there ways to sniff data in real time?
My question is are there ways to sniff data in real time?
Depends how good your nose is, I guess. Personally, I've never smelt data. Even rotten data doesn't have an aroma.
You failed to post any code or any schematic, so we'll fail to help.
Funny though:-))) sorry for not posting th code currently at work thats the reason. Will post pater for sure.
just to note I`m using arduino uno + esp8266-01. Esp is getting voltage from separate voltage regulator 3.3v min 3.5v max measured,1.5A max output and filtered with 100uf and 0.1uf caps. Logic level converting did with 2 n-type mosftets with resistors. ESP tested with softserial works great. now code:
#define max_attempts 15
#define input_buffer 250
#define ipd 2
#define restart 1
#define at 2
#define uart 3
#define cwmode 4
#define cwdhcp 5
#define cipmux 6
#define cipservermaxconn 7
#define cipserver 8
#define cipsto 9
#define cwdhcps 10
#define cwsap 11
#define websend 12
#define sendok 13
#define homepagelength 235
#define ledPin 13
const char RST[] PROGMEM = "AT+RST";
const char AT[] PROGMEM = "AT";
const char UART[] PROGMEM = "AT+UART_DEF=115200,8,3,1,0";
const char CWMODE[] PROGMEM = "AT+CWMODE_DEF=3";
const char CWDHCP[] PROGMEM = "AT+CWDHCP_DEF=2,1";
const char CIPMUX[] PROGMEM = "AT+CIPMUX=1";
const char CIPSERVERMAXCONN[] PROGMEM = "AT+CIPSERVERMAXCONN=1";
const char CIPSERVER[] PROGMEM = "AT+CIPSERVER=1,80";
const char CIPSTO[] PROGMEM = "AT+CIPSTO=60";
const char CWDHCPS[] PROGMEM = "AT+CWDHCPS_DEF=1,5,\"192.168.4.10\",\"192.168.4.15\"";
const char CWSAP[] PROGMEM = "AT+CWSAP_DEF=\"mq2\",\"poseidon\",10,3";
const char CIPSEND[] PROGMEM="AT+CIPSEND=";
const char CIPCLOSE[] PROGMEM="AT+CIPCLOSE=";
byte process_text(char a[], byte _size);
byte receive_command(void);
byte id = 0;
byte send_command(byte command);
bool esp_init(void);
void input_buffer_flush(void);
bool client_checker(void);
void setup() {
pinMode(ledPin,OUTPUT);
digitalWrite(ledPin,LOW);
Serial.begin(115200); //if 9600 then delay(2)
while (!Serial);
delay(100);
while (!esp_init()) {digitalWrite(ledPin,!digitalRead(ledPin));};
// Serial.println("everything went ok");
}
void loop() {
if(client_checker()); //Serial.println("connection available");
}
bool esp_init(void){
bool success=1;
success&=send_command(restart);
success&=send_command(at);
success&=send_command(uart);
success&=send_command(cwmode);
success&=send_command(cwsap);
success&=send_command(cwdhcp);
success&=send_command(cwdhcps);
success&=send_command(cipmux);
success&=send_command(cipservermaxconn);
success&=send_command(cipserver);
success&=send_command(cipsto);
return success;
}
void input_buffer_flush(void){
char c=0;
while (Serial.available()){
if(Serial.available()>0) c=Serial.read();
delayMicroseconds(100);
digitalWrite(ledPin,!digitalRead(ledPin));}
return ;
}
byte process_text(char a[],byte _size){
byte answer=0;
if(a[0]=='S' && a[1]=='E' && a[2]=='N' && a[3]=='D' && a[5]=='O' && a[6]=='K') answer=13;
else if((a[0]=='+' && a[1]=='I' && a[2]=='P' && a[3]=='D')&&((a[5])-48)<5) {id=((a[5])-48);answer=2;}//needs to be checked ID is digit or ascii
else if((a[1]==',' && a[2]=='C' && a[3]=='O' && a[4]=='N' && a[5]=='N' && a[6]=='E' && a[7]=='C' && a[8]=='T')&&((a[0])-48)<5) {
id=((a[0])-48);
answer=3;}
else if(a[0]=='C' && a[1]=='L' && a[2]=='O' && a[3]=='S' && a[4]=='E' && a[5]=='D') {id=0;answer=4;}
else if(a[0]=='>') answer=12;
else if((a[0]=='O' && a[1]=='K') || (a[0]=='N' && a[1]=='O' && a[3]=='C' && a[4]=='H') || (a[0]=='r' && a[1]=='e' && a[2]=='a' && a[3]=='d' && a[4]=='y')) answer=1;
return answer;
}
byte receive_command(void) {
char c = 0;
char a[input_buffer] = {0};
byte b = 0;
while (!Serial.available());
for (byte i = 0; i < input_buffer && Serial.available(); i++) {
c = Serial.read();
digitalWrite(ledPin,!digitalRead(ledPin));
a[i] = c;
if (c == '\n') {
if ((b = process_text(a, i)) > 0) {
//input_buffer_flush();
break;
}
}
delayMicroseconds(100);
}
return b;
}
byte send_command(byte command) {
byte timout = 10;
bool text_response = 0;
char _command[100] = {0};
switch (command) {
case restart:
for (byte i = 0; i < strlen_P(RST); i++) {
_command[i] = pgm_read_byte_near(RST + i);
}
break;
case uart:
for (byte i = 0; i < strlen_P(UART); i++) {
_command[i] = pgm_read_byte_near(UART + i);
}
break;
case at:
for (byte i = 0; i < strlen_P(AT); i++) {
_command[i] = pgm_read_byte_near(AT + i);
}
break;
case cwmode:
for (byte i = 0; i < strlen_P(CWMODE); i++) {
_command[i] = pgm_read_byte_near(CWMODE + i);
}
break;
case cwsap:
for (byte i = 0; i < strlen_P(CWSAP); i++) {
_command[i] = pgm_read_byte_near(CWSAP + i);
}
break;
case cwdhcp:
for (byte i = 0; i < strlen_P(CWDHCP); i++) {
_command[i] = pgm_read_byte_near(CWDHCP + i);
}
break;
case cwdhcps:
for (byte i = 0; i < strlen_P(CWDHCPS); i++) {
_command[i] = pgm_read_byte_near(CWDHCPS + i);
}
break;
case cipmux:
for (byte i = 0; i < strlen_P(CIPMUX); i++) {
_command[i] = pgm_read_byte_near(CIPMUX + i);
}
break;
case cipservermaxconn:
for (byte i = 0; i < strlen_P(CIPSERVERMAXCONN); i++) {
_command[i] = pgm_read_byte_near(CIPSERVERMAXCONN + i);
}
break;
case cipserver:
for (byte i = 0; i < strlen_P(CIPSERVER); i++) {
_command[i] = pgm_read_byte_near(CIPSERVER + i);
}
break;
case cipsto:
for (byte i = 0; i < strlen_P(CIPSTO); i++) {
_command[i] = pgm_read_byte_near(CIPSTO+i);
}
break;
default:
break;
}
do {
if (timout > max_attempts) return text_response;
input_buffer_flush();
timout++;
Serial.println(_command); //println will add \r\n at the end of command
delayMicroseconds(100);
text_response = receive_command();
} while (!text_response);
return text_response;
}
void home_page(void){
Serial.print(F("HTTP/1.1 200 OK\n"));
Serial.print(F("Accept-Ranges: bytes\n"));
Serial.print(F("Content-Type: text/html\n"));
Serial.print(F("\n"));
Serial.print(F("<!DOCTYPE HTML>"));
Serial.print(F("<html>"));
Serial.print(F("<title> room 1 </title>"));
Serial.print(F("<head>"));
Serial.print(F("</head>"));
Serial.print(F("<body>"));
Serial.print(F("<p>"));
Serial.print(F("Temperature:"));
//Serial.println temperature variable
Serial.print(F("</p>"));
Serial.print(F("<p>"));
// Serial.println humidity variable
Serial.print(F("</p>"));
Serial.print(F("<p>"));
//Serial.println co level variable
Serial.print(F("</p>"));
Serial.print(F("</body>"));
Serial.print(F("</html>"));
Serial.print(F("Client disonnected"));
Serial.print(F("\n"));
return;
}
bool client_checker(void){
byte c=0;
char _command[100]={0};
if(Serial.available()>0){
c=(receive_command());
}
switch(c){
case ipd:
for (byte i = 0; i < strlen_P(CIPSEND); i++) {
_command[i] = pgm_read_byte_near(CIPSEND + i);
}
Serial.print(_command);
Serial.print(id);
Serial.print(',');
Serial.println(homepagelength);
break;
case websend:
home_page();
break;
case sendok:
for (byte i = 0; i < strlen_P(CIPCLOSE); i++) {
_command[i] = pgm_read_byte_near(CIPCLOSE + i);
}
Serial.print(_command);
Serial.println(id);
break;
default:
break;
}
return c;
}
void loop() {
if(client_checker()); //Serial.println("connection available");
}
Why is the call to client_checker() wrapped in a useless if statement?
Why does loop() do nothing more than call one other function?
success&=send_command(restart);
Isyourspacekeybroken?
if(a[0]=='S' && a[1]=='E' && a[2]=='N' && a[3]=='D' && a[5]=='O' && a[6]=='K') answer=13;
Are you serious? Get real. Learn to use memcmp().
for (byte i = 0; i < input_buffer && Serial.available(); i++) {
c = Serial.read();
digitalWrite(ledPin,!digitalRead(ledPin));
a[i] = c;
This will spin through this loop VERY quickly, splattering data all over the a array (what a stupid name).
It will NOT fill the a array in order.
c=(receive_command());
(Why) (is) (the) (call) (wrapped) (in) (useless) (parentheses) (?)
I gave up trying to understand the code, with the useless names for the variables.
Client_checker is wrapped in if statement because i stopped right there its not a finished code. There is no need for now to call for other functions.
Didnt get whats wrong with using _ ?
Thanks for suggestion will follow to learn memcmp.
For loop is fast but you didnt noticed delay() i guess. Besides this loop was tested via serial monitor even with sending very long strings char array was arranged properly from position [0] to the length of the string. C=(receivecommand()) dont know why put extra parentheses but its not changing property of that function even if i will add 100 of opening and closing parentheses.
int memcmp (const void *a1, const void *a2, size_t size). My array is not const how to use with memcmp?
Didnt get whats wrong with using _ ?
Thereisnothingwrongwithusingunderscores. The problem is writing code without white space. The compiler doesn't care, but you didn't ask the compiler what was wrong with your code. You asked people, and people DO care about white space.
For loop is fast but you didnt noticed delay()
Saw it. Thought it stupid. There is NO guarantee that sticking your head in the sand for ANY length of time will make another byte arrive on the serial port.
My array is not const how to use with memcmp?
Understand what const means there. It means that memcmp() will not alter the input data in any way. It does NOT mean that the array must be const.
I reread that for loop, agree if within 100microseconds nothing will arrive it will skip the whole function as &&serial.available() will not be true. I added that 100 microsecond delay for that purpose. Was thinking of checking size of serial available but size will vary at different times one time will be 3 the other times 50 depending what i am expecting to arrive. Making delay longer will fill serial 64byte buffer and new data will not arrive. Any suggestions? By the way 100 microseconds were calculated as per 115200bps. 115200/8bits=14400bytes per second. 14400/1000’000microseconds=69.4microsecond gap or window between characters. So wait time of 70microseconds shouldnt be enough?
Any suggestions?
Yes. Stop expecting all serial data to arrive within some defined period of time. Look at Ronin2's tutorial (again and again, if needed). Deal with the arrival of serial data as it arrives. USE the data that has arrived ONLY when the end-of-packet marker (whatever that is, in your case) arrives. You will NOT find delay(), or any variation of it, anywhere in Robin2's tutorial.
Thanks actually have read Robin2’s tutorial but have to go over again i guess. But in my first post i was wondering if there is a way to sniff that data as i said. To actually see how they are communicating. Because using serial monitor for both everything is going as expected but when they are hooked up together then is the same as looking at the picture with closed eyes.
Ok now im really confused. After reading Robin2’s tutorial for receiving string didnt find any difference with my approach. Both are reading serial data when available both have array size limit and end markers too. In my case endmarker is end of the line.
After reading Robin2's tutorial for receiving string didnt find any difference with my approach.
Post Robin2's approach, with the delay() call clearly marked.
If time in receiving byte from serial cant be faster than 69.4microseconds why my 100microseconds can hurt?
surepic:
If time in receiving byte from serial cant be faster than 69.4microseconds why my 100microseconds can hurt?
Because it does not GUARANTEE that there will be data to read. And, you assume that there is.
You COULD get rid if the delayMicroseconds() call, and the i++ at the end of the for statement. When you do successfully read a byte, then increment i.
Nice explanation.
after trials and errors
byte receive_command(void) {
char c = 0;
char a[input_buffer] = {0};
byte b = 0;
unsigned long _time = 0;
const int max_wait_time = 10000;
_time = millis();
byte i = 0;
while (!Serial.available()) {
if ((millis() - _time) > max_wait_time) return b;
}
while((c=Serial.read())!='\n'){
digitalWrite(ledPin, !digitalRead(ledPin));
a[i] = c;
i++;
}
a[i+1]='\0';
b = process_text(a, i+1);
return b;
}
char a[input_buffer] = {0};
You know that input_buffer is NOT an input buffer, right? So, it is a completely meaningless name for an array index. All that that will do is lead to confusion later on.
start to move forward little modified the code and again question about Serial.
small note mySerial and Serial are same in this code #defined mySerial Serial
//void sendcommand function everything is same except commented lines
for (byte i = 0; i < (strlen(_command)); i++) {
mySerial.write(_command[i]);
delay(1);
}
mySerial.flush(); //added output buffer flush for arduino to wait till output buffer will be empty then do whatever suppose to do.
this is init function which now sends command via function then checks response via other function
send_command(restart);
success &= receive_command("OK");
serial_flush();
send_command(bla);
success &= receive_command("OK");
serial_flush();
Serial.println(success);
changed receive function completely
bool receive_command(char answer[]) {
unsigned long _time = 0;
const int max_time = 10000;
bool flag = 0;
_time = millis();
Serial.println(Serial.available()); // Attention to this line!
while (Serial.available() < 2) { // waiting for buffer to be at least 2 byte
if ((millis() - _time) > max_time) return flag; // can wait for max_time
}
do {
//delay(10); this delay is correcting that 32byte problem.
_time = millis(); //update timer
if (Serial.findUntil(answer, '\n')) return flag = 1; // if answer is found within terminating char exit
} while (Serial.available() && (millis() - _time) < max_time); // do while Serial.available returns !0 and time is within reasonable limit.
return flag; // will return 0 anyway.
}
and serial input buffer flush
void serial_flush(void) {
while (Serial.available()) Serial.read();
}
now I`m sending this string via serial monitor
saodijosadifjasodifjaosi;djfaosidfj
OKsdoifja;osidjf;oaisjdf;oiasjdf
right after OK if you count there are 30 chars in red plus CR and LF i.e. 32byte.
when second send command is executed sending "bla" that 32 bytes are still in input buffer . and it automatically receives wrong string. I.e. leftover from first one which flush function supposed to clean.
If I am adding delay of 10 milliseconds in receive function . that 32 bytes are emptied.
why I need to slow things down to flush the buffer? Can someone read the code and pinpoint where I`m going wrong again ?
thanks