I have written a solver with MPI but it crashes or hang on when the number of tasks is larger than 80 on a cluster. Sometimes, it crashes and sometimes it hangon with the changing of the testing code and with the changing of the task number. At first I thought there might be some memory leak before the failing point which result in the failure. But After some testing, I found that even I only do a simple data transfer at the beginning of the solver, it also crashes. This time it only crashes without hang on.
My question is:
Is there any mistake in the subroutine TestMPI() which results in the crash?
If the answer to the first question is no, what is the possible reason of this crash?
Thanks!
I attached the solver as following, the function of the data transfer is:
void TestMPI()
{
int check = 1;
MPI_Bcast(&check, 1, MPI_INT, 0, MPI_COMM_WORLD);
int N_region = 0;
MPI_Comm_size(MPI_COMM_WORLD, &N_region);
int mpi_Rank=0;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_Rank);
MPI_Request * reqSend_test = new MPI_Request [N_region];
MPI_Request * reqRecv_test = new MPI_Request [N_region];
MPI_Status * status_test = new MPI_Status [N_region];
MPI_Status statRecv;
int cnt_test(0);
double * Read_test = new double[N_region];
double * Send_test = new double[N_region];
for (int ii=0; ii<N_region; ii++)
{
if (ii == mpi_Rank)
continue;
int tag = (ii) * N_region + mpi_Rank;
MPI_Irecv(&Read_test[ii],1,MPI_DOUBLE,ii,tag,MPI_COMM_WORLD,&reqRecv_test[ii]);
cnt_test++;
}
cnt_test = 0;
for (int ii=0; ii<N_region; ii++)
{
if (ii == mpi_Rank)
continue;
Send_test[ii] = mpi_Rank;
int tag = (mpi_Rank)*N_region + ii;
MPI_Isend(&Send_test[ii],1,MPI_DOUBLE,ii,tag,MPI_COMM_WORLD,&reqSend_test[ii]);
cnt_test++;
}
//MPI_Waitall(N_region-1, reqSend_test, status_test);
char fname [80];
sprintf(fname, "TestMPI_result%d", mpi_Rank);
FILE * stream = fopen(fname,"w");
fprintf(stream, "After MPI_Waitall send\n");
fflush(stream);
for (int ii=0; ii<N_region; ii++)
{
if (ii == mpi_Rank)
continue;
MPI_Wait(&reqSend_test[ii], &statRecv);
fprintf(stream, "After Wait Send %d\n", ii);
fflush(stream);
}
for (int ii=0; ii<N_region; ii++)
{
if (ii == mpi_Rank)
continue;
MPI_Wait(&reqRecv_test[ii], &statRecv);
fprintf(stream, "After Wait Recv %d\n", ii);
fflush(stream);
}
fprintf(stream, "After Start Test\n");
fflush(stream);
//MPI_Waitall(N_region-1, reqRecv_test, status_test);
MPI_Bcast(&check, 1, MPI_INT, 0, MPI_COMM_WORLD);
fprintf(stream, "After MPI_Bcast\n");
fflush(stream);
fclose(stream);
}
The main function calling this data transfer function is ( The code before calling the TestMPI() is to create the simulation folder for slave tasks. )
int main(int argc, char* argv[])
{
int ISV_LIC = 17143112; // For Platform Computing mpi initialization
MPI_Initialized(&ISV_LIC);
int threadingUsed = 0;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &threadingUsed);
int mpi_Rank=0;
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_Rank);
if (mpi_Rank == 0)
{
std::cerr << "solverok" << std::endl;
std::cerr.flush();
AnsDebug(ACHAR("3dtds-main"), 1, ACHAR("After solverok\n"));
}
AString simulationDir_master;
AString simulationDir;
AString tempDir;
simulationDir_master=argv[argc-3];
ANSOFT_CHDIR(simulationDir_master.ANS_ANSI().Str()); //simulationDir_master;
mpi_BcastEnvVariables();
bool no_temp_dir_override;
no_temp_dir_override = false;
for (int ii=0; ii<argc; ii++)
{
if (strcmp(argv[ii], "no_temp_dir_override") == 0)
{
no_temp_dir_override = true;
break;
}
}
AString Dbname;
Dbname=argv[5];
AString versionedProductName;
versionedProductName = argv[argc-4];
AString InstallDir;
char InstallDir_c[MAX_PATH];
ANSOFT_GETCWD(InstallDir_c, MAX_PATH);
InstallDir=AString(InstallDir_c);
if (mpi_Rank != 0)
{
if (!no_temp_dir_override)
{
tempDir=argv[argc-1];
}else{
RegistryAccessNgMaxwell reg;
tempDir = reg.GetTempDirectory_Reg(versionedProductName,InstallDir);
tempDir = tempDir.Left(tempDir.size()-1);
}
#ifndef NDEBUG
tempDir = "E:/temp";
#endif
CreateSimulationDir(mpi_Rank, tempDir, Dbname, ACHAR("maxwell"), simulationDir);
ANSOFT_CHDIR(simulationDir.ANS_ANSI().Str());
}
char fname [80];
sprintf(fname, "RecordMPI%d",mpi_Rank);
FILE * stream = fopen(fname,"w");
fprintf(stream, "Before testMPI\n");
fflush(stream);
TestMPI();
fprintf(stream, "After testMPI\n");
fflush(stream);
fclose(stream);
MPI_Finalize();
}
The output files of task 79 is the following which shows the crashing point.
After MPI_Waitall send
After Wait Send 0
After Wait Send 1
After Wait Send 2
After Wait Send 3
After Wait Send 4
After Wait Send 5
After Wait Send 6
After Wait Send 7
After Wait Send 8
After Wait Send 9
After Wait Send 10
After Wait Send 11
After Wait Send 12
After Wait Send 13
After Wait Send 14
After Wait Send 15
After Wait Send 16
After Wait Send 17
After Wait Send 18
After Wait Send 19
After Wait Send 20
After Wait Send 21
After Wait Send 22
After Wait Send 23
After Wait Send 24
After Wait Send 25
After Wait Send 26
After Wait Send 27
After Wait Send 28
After Wait Send 29
After Wait Send 30
After Wait Send 31
After Wait Send 32
After Wait Send 33
After Wait Send 34
After Wait Send 35
After Wait Send 36
After Wait Send 37
After Wait Send 38
After Wait Send 39
After Wait Send 40
After Wait Send 41
After Wait Send 42
After Wait Send 43
After Wait Send 44
After Wait Send 45
After Wait Send 46
After Wait Send 47
After Wait Send 48
After Wait Send 49
After Wait Send 50
After Wait Send 51
After Wait Send 52
After Wait Send 53
After Wait Send 54
After Wait Send 55
After Wait Send 56
After Wait Send 57
After Wait Send 58
After Wait Send 59
After Wait Send 60
After Wait Send 61
After Wait Send 62
After Wait Send 63
After Wait Send 64
After Wait Send 65
After Wait Send 66
After Wait Send 67
After Wait Send 68
After Wait Send 69
After Wait Send 70
After Wait Send 71
After Wait Send 72
After Wait Send 73
After Wait Send 74
After Wait Send 75
After Wait Send 76
After Wait Send 77
After Wait Send 78
After Wait Send 80
After Wait Send 81
After Wait Send 82
After Wait Send 83
After Wait Send 84
After Wait Send 85
After Wait Send 86
After Wait Send 87
After Wait Send 88
After Wait Send 89
After Wait Send 90
After Wait Send 91
After Wait Send 92
After Wait Send 93
After Wait Send 94
After Wait Send 95
After Wait Send 96
After Wait Send 97
After Wait Send 98
After Wait Send 99
After Wait Send 100
After Wait Send 101
After Wait Send 102
After Wait Send 103
After Wait Send 104
After Wait Recv 0
After Wait Recv 1
After Wait Recv 2
After Wait Recv 3
After Wait Recv 4
After Wait Recv 5
After Wait Recv 6
After Wait Recv 7
After Wait Recv 8
After Wait Recv 9
After Wait Recv 10
After Wait Recv 11
After Wait Recv 12
After Wait Recv 13
After Wait Recv 14
After Wait Recv 15
After Wait Recv 16
After Wait Recv 17
After Wait Recv 18
After Wait Recv 19
After Wait Recv 20
After Wait Recv 21
After Wait Recv 22
After Wait Recv 23
After Wait Recv 24
After Wait Recv 25
After Wait Recv 26
After Wait Recv 27
After Wait Recv 28
After Wait Recv 29
After Wait Recv 30
After Wait Recv 31
Related
I am running ESP8266_RTOS_SDK_3.4 for an app that uses TCP to talk to a private port on a local server. In normal operation, it uploads large amounts of data to the server and receives acknowledgements that are usually less than 200 bytes: this always works fine. When I do an OTA update, where it's mainly receiving data, TCP recv fails on attempting to read the first block, and errno is set to 11 (EAGAIN). Even if I make the server send just 1024 bytes, the same thing happens.
This is the TCP connect and recv code:
bool net_tcp_connect (SENDER_DESTINATION * dest) {
struct sockaddr_in destAddr;
if (!find_host (dest->hostname)) {
return false;
}
memset(&destAddr, 0, sizeof(destAddr));
memcpy (&destAddr.sin_addr, findhost_ip (), sizeof (destAddr.sin_addr));
destAddr.sin_family = AF_INET;
destAddr.sin_port = htons (dest->port);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
LOGEF("Create: errno %d", errno);
return false;
}
struct timeval tv;
tv.tv_sec = dest->timeout;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));
if (connect(sock, (struct sockaddr *)&destAddr, sizeof(destAddr)) != 0) {
LOGEF("Connect: %s %d errno %d", findhost_str (), dest->port, errno);
EVENT_HERE ( );
net_tcp_close ();
return false;
}
return true;
}
// --------------------------------------------------------------------------------------------
int net_tcp_recv (void * buffer, int max_length) {
if (sock < 0)
return false;
int bytes_received = recv (sock, buffer, max_length, 0);
if (bytes_received < 0) {
LOGEF("Receive: errno= %d", errno);
net_tcp_close ();
bytes_received = 0;
}
return bytes_received;
}
EAGAIN can be a sign of a receive timeout, but the timeout is set to 30 seconds and the server usually sends out the first 32k bytes in less than a second.
The ESP8266 code does run OK on some access points and, as far as I can tell, the same code on an ESP32 runs OK on all access points.
Any suggestions for why this might happen, or things that I could try changing in the code or the ESP setup to make it work reliably on any access point?
I got an MPU connected to a wemos d1 mini. The sensor send 3 values: X,Y and Z axis. Since my project is solar powered I need to reduce power consumption. In order to do so I want to read the 3 values of the MPU every 3 seconds, store the values in an array and after 5 minutes of sampling power up the wifi and send the array via mqtt to my topic.
I've already tested every part of my code and everything works.
For example if I try to send an array of three objects it works perfectly
But when I try to send an array of 100 objects it doesn't work.
(Note: Where the above "100" come from? If I need to send data every 5 minutes and I read values every 3 seconds here I have 100 samplings)
Hope someone could help
unsigned long t_start;
void setup()
{
t_start = millis();
}
//compute the required size
const size_t CAPACITY = JSON_ARRAY_SIZE(100) + 100 * JSON_OBJECT_SIZE(3);
//allocate the memory for the document
StaticJsonDocument<CAPACITY> doc;
//MPU
const int MPU = 0x68; // I2C address of the MPU-6050
int16_t AcX, AcY, AcZ;
void loop()
{
//Create an empty array
JsonArray arr = doc.to<JsonArray>();
if (millis() - t_start >= 3000) {
for (int i = 0; i < 100; i++) {
//MPU reading
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Create a JSON Object
JsonObject obj = doc.createNestedObject();
obj["AcX"] = AcX;
obj["AcY"] = AcY;
obj["AcZ"] = AcZ;
}
t_start = millis();
}
}
//MQTT PUBLISHING JSON PACKAGE
char mqttData[MQTT_BUFFER];
serializeJson(doc, mqttData);
Serial.println(mqttData);
int ret = client.publish("esp8266/JSON", mqttData);
} //end of loop
If you want one measure every three seconds instead of 100 measures every 3 seconds, the code should look like this:
#define MQTT_KEEPALIVE 300
// headers ...
// setup() ...
void loop() {
//Create an empty array
JsonArray arr = doc.to<JsonArray>();
static auto t_start = millis(); // static will preserve last value even after exiting loop
int8_t count = 0;
while (count < 100) { // stays here whole 300s, so if the keep alives are needed or doing something else, it should be inside too
client.loop(); // sugested in comments
if (millis() - t_start >= 3000) {
t_start += 3000;
++count;
//MPU reading
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Create a JSON Object
JsonObject obj = doc.createNestedObject();
obj["AcX"] = AcX;
obj["AcY"] = AcY;
obj["AcZ"] = AcZ;
}
// handling keep alives every X seconds as it's unlikely as long as 300s:
// if (...) sendKeepAlive();
}
// after 100 measures it'll get here:
//MQTT PUBLISHING JSON PACKAGE
char mqttData[MQTT_BUFFER];
serializeJson(doc, mqttData);
Serial.println(mqttData);
int ret = client.publish("esp8266/JSON", mqttData);
} //end of loop
However it should solve just most obvious issue with the code only. There might be others, like buffers might be too small, or so...
And it's untested, I don't have this HW setup
I am building a C# windows form program that will communicate with an ESP8266. I am hoping to not have to post too much code as the both the programs are fairly large. I will try to explain my issue as best as I can;
The C# program is sending a packet over UDP broadcast while connected to the ESP8266 soft access point. The ESP8266 can receive and parse the packet just fine from the C# form. The problem is I am trying to send a response packet immediately back to the C# form. This is where the problem is occurring. The ESP8266 will get hung/freeze for a bit either when calling the "write()" or when calling "endPacket()" and then it will crash. Sometimes "endPacket()" will actually not get hung/freeze and send the response packet back, but it will still crash immediately after.
The error output most of the time seems to be: "ets Jan 8 2013,rst cause:4, boot mode:(3,6)". However sometimes it is different.
I have tried using the "yield()" function throughout my code as well but no luck.
Any guidance or solutions are appreciated!?
ESP8266 Program: Main code in question:
bool BatteryOptimizer::ProcessData()
{
size_t enc_data_len = 0;
size_t dec_data_len = 0;
//int ass_data_size_temp = 0;
char encrypted_data[BO_UDP_PACKET_SIZE];
char decrypted_data[BO_UDP_PACKET_SIZE];
char associated_data_temp[BO_AES_ASSOCIATED_DATA_SIZE];
uint8_t iv[GCM_AES_256_IV_TAG_SIZE];
uint8_t tag[GCM_AES_256_IV_TAG_SIZE];
bool status = false;
uint8_t msg_type = 0;
char response_packet[BO_PACKET_SIZE];
size_t response_packet_size = BO_PACKET_SIZE;
msg_type = (uint8_t)BatteryOptimizer::collector_manager->fields[1].ui64_field; //Get Msg Type
//See if Message type is correct first before continuing
if (msg_type < BO_AES_ASSOCIATED_DATA_SIZE)
{
enc_data_len = (size_t)(collector_manager->fields[3].ui64_field - GCM_AES_256_IV_TAG_SIZE); //Get encrypted data length
memcpy(iv, BatteryOptimizer::collector_manager->fields[2].c_array, GCM_AES_256_IV_TAG_SIZE); //Get IV
memcpy(encrypted_data, BatteryOptimizer::collector_manager->fields[3].c_array, enc_data_len); //Get encrypted data
memcpy(tag, BatteryOptimizer::collector_manager->fields[3].c_array + enc_data_len, GCM_AES_256_IV_TAG_SIZE); //Get tag
//ass_data_size_temp = BatteryOptimizer::associated_data[msg_type].length(); //Get associated data legnth
BatteryOptimizer::associated_data[msg_type].toCharArray(associated_data_temp, BO_AES_ASSOCIATED_DATA_SIZE); //Get associated data
//Decrypt data
Serial.println("ProcessData: Attempting to decrypt data!");
status = Decrypt_GCM_AES256((uint8_t *)encrypted_data,
enc_data_len,
iv,
tag,
associated_data_temp,
(uint8_t *)decrypted_data,
&dec_data_len);
if (true == status)
{
//Execute command:
BatteryOptimizer::ExecuteCommand(msg_type, decrypted_data, dec_data_len);
//Build Reponse packet:
Serial.println("ProcessData: Attempting to build Reponse packet!");
memset(response_packet, 0, BO_PACKET_SIZE);
BatteryOptimizer::BuildResponsePacket(associated_data_temp, response_packet, &response_packet_size);
//Send Response packet:
Serial.println("ProcessData: Attempting to begin packet!");
Serial.println("ProcessData: Remote IP: ");
Serial.println(BatteryOptimizer::udp_server.remoteIP());
Serial.println("ProcessData: Remote Port: ");
Serial.println(BatteryOptimizer::udp_server.remotePort());
status = BatteryOptimizer::udp_server.beginPacket(BatteryOptimizer::udp_server.remoteIP(), BatteryOptimizer::udp_server.remotePort());
if (true == status)
{
Serial.println("ProcessData: Attempting to write packet!");
Serial.println(BatteryOptimizer::udp_server.write(response_packet, response_packet_size));
Serial.println("ProcessData: Attempting to send packet!");
status = BatteryOptimizer::udp_server.endPacket();
if (true == status)
{
Serial.println("ProcessData: UDP server sent reponse packet!");
}
else
{
Serial.println("ProcessData: UDP server was unable to send repsonse packet!");
Serial.println("ProcessData: Tried to send response packet: " + BatteryOptimizer::associated_data[msg_type]);
}
}
else
{
Serial.println("ProcessData: UDP server was unable to begin packet!");
Serial.println("ProcessData: Tried to send response packet: " + BatteryOptimizer::associated_data[msg_type]);
}
}
else
{
Serial.println("ProcessData: Failed to process data!");
//Testing
Serial.println("Encrypted length: ");
Serial.println(enc_data_len);
Serial.println("Decrypted Data: ");
Serial.println(decrypted_data);
Serial.println(decrypted_data + 50);
Serial.println("Associated Data: ");
Serial.println(associated_data_temp);
}
}
return status;
} //END ProcessData
void BatteryOptimizer::UDP_ServerLoop()
{
char packet[BO_UDP_PACKET_SIZE];
int packetSize;
Serial.println("UDP server about to start parsing packets!");
//while (BatteryOptimizer::run_udp == true)
if (BatteryOptimizer::run_udp == true)
{
packetSize = BatteryOptimizer::udp_server.parsePacket();
if (packetSize > 0)
{
Serial.println("Received packet! Size: ");
Serial.println(packetSize);
size_t len = (size_t)BatteryOptimizer::udp_server.read(packet, BO_UDP_PACKET_SIZE);
if (len > 0)
{
BatteryOptimizer::collector_manager->Collect(packet, &len);
if (COLLECT_FOUND == BatteryOptimizer::collector_manager->status)
{
Serial.println("Found msg!");
Serial.println("Collected Packet Size:");
Serial.println(BatteryOptimizer::collector_manager->packet_size);
BatteryOptimizer::collector_manager->Check_Checksum();
if (COLLECT_VALID_CS == BatteryOptimizer::collector_manager->status)
{
Serial.println("Valid Checksum!");
BatteryOptimizer::collector_manager->Parse();
//Process data
if (true == BatteryOptimizer::ProcessData())
{
Serial.println("Process success!");
}
}
else
{
Serial.println("Invalid Checksum!");
}
BatteryOptimizer::collector_manager->ResetCache();
}
else
{
Serial.println("Did not find a message!");
}
}
else
{
Serial.println("Did not receive a complete packet!");
}
}
else
{
Serial.println("Packet size is 0!");
}
Serial.println("Packet received: ");
Serial.println(packet);
delay(BO_UDP_DELAY);
} //END run_udp loop
Serial.println("UDP server no longer parsing packets! ");
} //END UDP_ServerLoop
void BatteryOptimizer::UDP_StartServer()
{
if (BatteryOptimizer::is_udp_running == false)
{
Serial.println("Starting UDP server. ");
BatteryOptimizer::udp_server.begin(BO_UDP_PORT);
Serial.println("Listening on UDP port ");
Serial.println(BO_UDP_PORT);
BatteryOptimizer::run_udp = true;
BatteryOptimizer::is_udp_running = true;
}
} //END UDP_StartServer
C# Windows Form: Main code in question:
private void UDP_Initialize_Client()
{
//Start UDP server to listen in for the Battery Opetimizer device:
udp_client = new UdpClient( listenPort );
end_point = new IPEndPoint( IPAddress.Broadcast, listenPort );
udp_client.EnableBroadcast = true;
udp_client.MulticastLoopback = false;
}
private void UDP_ReceiveContinuously( IAsyncResult res )
{
byte[] received = udp_client.EndReceive( res, ref end_point );
//Process Data:
UDP_ProcessData( ref received );
UDP_SetupReceive();
} //END UDP_ReceiveContinuously
private void UDP_SetupReceive()
{
try
{
udp_client.BeginReceive( new AsyncCallback( UDP_ReceiveContinuously ), null );
}
catch (Exception e)
{
MessageBox.Show( e.ToString() );
}
} //END UDP_SetupReceive
As an update, I figured out how to use the exception decoder. Here are is the output;
0x40206afe: raise_exception at core_esp8266_postmortem.cpp line ?
0x40206b10: __assert_func at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/core_esp8266_postmortem.cpp line 275
0x40100ba2: get_unpoisoned_check_neighbors at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_local.c line 125
0x402074bd: uart_write at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/uart.cpp line 509
0x40100c91: umm_poison_free_fl at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_local.c line 148
0x40205690: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
0x4010038c: free at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/heap.cpp line 259
0x40205690: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
0x4020ebe5: operator delete(void*) at /workdir/repo/gcc/libstdc++-v3/libsupc++/del_op.cc line 48
0x4020ebd0: operator delete[](void*) at /workdir/repo/gcc/libstdc++-v3/libsupc++/del_opv.cc line 33
0x40204b40: Collector::FreeUnnecessaryResources() at D:\Projects\Arduino\libraries\DataHandler/DataHandler.cpp line 331 (discriminator 3)
0x40201912: BatteryOptimizer::UDP_OnPacket(AsyncUDPPacket) at C:\Users\SPENCE~1\AppData\Local\Temp\arduino_build_863316\sketch/battery_optimizer.cpp line 312 (discriminator 1)
0x4020105f: BP_OnPacket(AsyncUDPPacket&) at D:\Projects\Arduino\ESP8266\BatteryPerserver/BatteryPerserver.ino line 55
0x40208910: precache at ?? line ?
0x40102b12: wDev_ProcessFiq at ?? line ?
0x402082c0: std::_Function_handler ::_M_invoke(std::_Any_data const&, AsyncUDPPacket&) at c:\users\spencerbell\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-4-b40a506\xtensa-lx106-elf\include\c++\4.8.2/functional line 2073
0x40202da2: AsyncUDP::_recv(udp_pcb*, pbuf*, ip4_addr*, unsigned short) at D:\Projects\Arduino\libraries\ESPAsyncUDP\src/AsyncUDP.cpp line 197
0x40208910: precache at ?? line ?
0x40221f4b: cnx_start_handoff_cb at ?? line ?
0x401009a5: check_poison_neighbors$part$3 at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_local.c line 71
0x40100a61: umm_malloc_core at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_malloc.cpp line 458
0x40101a17: ppCalFrameTimes at ?? line ?
0x40202dd8: AsyncUDP::_s_recv(void*, udp_pcb*, pbuf*, ip4_addr const*, unsigned short) at D:\Projects\Arduino\libraries\ESPAsyncUDP\src/AsyncUDP.cpp line 210
0x4021314c: udp_input at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/lwip2-src/src/core/udp.c line 404
0x4022eb18: pbuf_alloc at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/glue-esp/lwip-esp.c line 669
0x40217cf0: ip4_input at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/lwip2-src/src/core/ipv4/ip4.c line 1461
0x40100c77: umm_free at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_malloc.cpp line 398
0x4020f349: ethernet_input_LWIP2 at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/lwip2-src/src/netif/ethernet.c line 188
0x4020f168: esp2glue_ethernet_input at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/glue-lwip/lwip-git.c line 469
0x4022ebfe: ethernet_input at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/glue-esp/lwip-esp.c line 365
Well after weeks of searching and modifying code. I figured out I was simply just using too much memory. I found several places in my code where I cut down array sizes and now its working perfect!
As a note, I also switched to using the ESPAsyncUDP library: https://github.com/me-no-dev/ESPAsyncUDP
I thought I solved that problem but while being at 80% of my project I discovered that its core has a terrible malfunction. I hope you guys are going to help me.
I have an Arduino with buttons. Pressing those buttons sends 1 for the first button, 2 for the second button, 4 for the third and so on - powers of number 2.
If I press the first and second button, it gives me the value 3. If there is no button pressed I get 0. Arduino has 8 buttons, so pressing all buttons together returns 511. The number is being sent only on button change. So it doesn't send a number continuously, but only on change. All that works perfectly fine.
I also have an ESP8266 module connected to the Arduino's TX and RX pins (pin 0 and 1). I can send data via Serial1.print to the ESP module. The ESP module sends data that comes from the Arduino to the local network and it is received by a Windows application on a specified port. All that works.
So if I press button 3 it goes like this:
button press -> analyze which button is pressed
-> send digit 4 to ESP
-> ESP gets data from Arduino
-> ESP sends digit 4 to the port on the web server
The problem comes when I start to press buttons like crazy as fast as I can (I expect such behaviour from users). I expect from my web server to get:
4 0 4 0 4 0 4 0 4 0
And so on because I press and release a button.
Unfortunately I sometimes get something like this:
4 0 4 0 4 0 4 4 0 4
It happens 2-3 times on 100 presses. As you can see, one of the button releases was lost. I tried many ways and I am almost sure that the ESP didn't send that missing 0, but surely it has been sent to the ESP. Probably it didn't get it from the Arduino and the problem lays within the readStringUntil function.
Here is the Arduino code:
String serialResponse = "";
void setup() {
Serial.begin(9600);
Serial1.begin(256000);
Serial.setTimeout(5);
Serial1.setTimeout(5);
for (int i = 0; i < numberOfButtons; i++) button[i] = i + startPin;
for (int i = 0; i < numberOfButtons; i++) buttonStatus[i] = false;
for (int i = 0; i < numberOfButtons; i++) pinMode(button[i], INPUT_PULLUP);
}
void loop() {
if (Serial.available()) {
serialResponse = Serial.readStringUntil('\r\n');
Serial1.println(serialResponse);
Serial.println(serialResponse);
}
int currentButtonValue = 0;
for (int i=0; i < numberOfButtons; i++) {
currentButtonValue = currentButtonValue + int(buttonStatus[i] * (0.5 + pow(2, i)));
}
if (currentButtonValue != previousButtonStatus ) {
previousButtonStatus = currentButtonValue;
Serial1.println(currentButtonValue);
Serial.println(currentButtonValue);
}
}
And here is my ESP code:
#include <ESP8266WiFi.h>
const char* ssid = "xxx";
const char* pass = "xxx";
const char* host = "192.168.0.10";
int port = 7777;
WiFiClient client;
void setup() {
Serial.begin(256000);
Serial.setTimeout(5);
WiFi.begin(ssid, pass);
while(WiFi.status() != WL_CONNECTED) {
Serial.print(".");
}
Serial.println("\nStarting connection to server...");
if (client.connect(host, port)) {
Serial.println("Connected to server.");
client.print("WIFI Module connected:" + WiFi.localIP());
}
}
void loop() {
if (client.available()) {
String WiFiResponse = client.readStringUntil('\n');
Serial.println(WiFiResponse);
}
if (Serial.available()) {
String SerialResponse = Serial.readStringUntil('\r\n');
client.print(SerialResponse);
}
if (!client.connected()) {
Serial.println();
Serial.println("Disconnecting from server.");
client.stop();
while(true);
}
What I checked that didn't help:
monitored in the same time Serial in Arduino and console in Windows app. Arduino sends the correct return values on button presses, the app sometimes misses something.
changing baud in both codes: 9600, 57600, 115200, 256000
changing settimeout value up to 500 hoping the longer time it will wait it will grab that missing 0.
tried different end of line delimiters for readStringUntil - \r \n and \r\n
I decided to use readStringUntil because there is a different amount of bytes being sent to the ESP. I sometimes also get different signs from ESP instead of digits for example "¦Hø".
Is there something I am doing wrong?
Thanks in advance!
I have problems with serial communications microcontroler 8051. My hardware MCU with att7035au and module-1350M CJH NFC reader. I have tested the pc and mcu to receive and transmit with usb-ttl / rs232 goes well. for sending 1 character and length data successfully without error. But after I try communication between mcu with NFC module there is an error during the receive data from the NFC. I use an interrupt to receive the data.
example :
mcu send (hex data):
02 55 00 03 03 E0 B7
NFC receiving data mcu and send feedback:
02 55 00 02 FF AA
mcu receive the data from NFC should (02 55 00 02 FF AA) but received
02 55 00 02 FF 05
What is wrong?why MCU read receive data error.
my code config:
BWPR = 0xcf;
BWPR = 0xbc;
PLLCFG = 0x87;
CLKCFG |= 0x04;
EA = 1;
//Serial config 0
SCON0 = 0x50 ; //SCON: serail mode 1, 8-bit UART
PCON|=0x80; //PCON.7 (SMOD) Indicate Baud rate double
SMOD_1=1; //ADCON.7
S0RELL=0xfd; //115200bps
S0RELH=0x03;
TI=0;
RI=0;
ES0 = 1 ;
edit add code interrupt:
void UART_0(void) interrupt 4
{
if(SCON0&0x01){ //RI=1
SCON0=SCON0&0xfc; //RI=0
card_id[RECE_NUMB]=SBUF0;
if(RECE_NUMB==6){
if(card_id[1]==0x02&&card_id[2]==0x55&&card_id[5]==0xff){
f_ReceiveSucceed=1;
SCON0&=0xef; //disable receive
}
}
++RECE_NUMB;
}
SCON0=0x50;
}
for code main(void):
while(1)
{
//...
//lines of code to send NFC
//...
if(f_ReceiveSucceed)
{
f_ReceiveSucceed=0;
SerialCommunication();
}
}
if get receive so i send to serialcommunication() for monitor data serial with usb-ttl
void SerialCommunication(void){
unsigned char count;
ES0 = 0;
for(count=0;count<=50;count++)
{
SBUF0=card_id[count];
while(TI==0);
TI=0;
}
ES0 = 1;
clear();
SCON0=0x50; //open receive
}
void clear(void)
{
unsigned char r;
for(r=0;r<50;r++){
card_id[r]=0x00;
}
RECE_NUMB=0;
}