hello everyone
So I have a project in which esp32 receive data from a gnss receiver at 5hz via i2c comunication and its actually running smooth, but when a change to 7hz it just dont work as smooth, is it because i2c have a default speed that isnt compatible with the one I want? or is it because esp32 takes too long to run the entire "void loop" part of the code, since it collect the data and save some of it on a sd card before collecting it again?
Probably your code... but hard to say unless you post it so we can have a look.
void loop(){
if(digitalRead(but) == HIGH) //funcitons based off of button pulling input pin HIGH
{
if(run == 0)
{
run = 255;
}
else
{
run = 0;
}
}
if(run > 0)
{
digitalWrite(yellow, LOW);
digitalWrite(green, HIGH);
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed.
while (myGNSS.fileBufferAvailable() >= sdWriteSize) // Check to see if we have at least sdWriteSize waiting in the buffer
{
myFile = sd.open("testFolder/RXM_RAWX.ubx", FILE_WRITE);
digitalWrite(LED, HIGH); // Flash LED_BUILTIN each time we write to the SD card
myGNSS.extractFileBufferData(myBuffer, sdWriteSize); // Extract exactly sdWriteSize bytes from the UBX file buffer and put them into myBuffer
//myFile.write(myBuffer, sdWriteSize); // Write exactly sdWriteSize bytes from myBuffer to the ubxDataFile on the SD card
myFile.write(myBuffer, sdWriteSize);
// In case the SD writing is slow or there is a lot of data to write, keep checking for the arrival of new data
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed.
digitalWrite(LED, LOW); // Turn LED_BUILTIN off again
}
}
if (millis() > (lastPrint + 1000)) // Print the message count once per second
{
Serial.print(F("Number of message groups received: SFRBX: ")); // Print how many message groups have been received (see note above)
Serial.print(numSFRBX);
Serial.print(F(" RAWX: "));
Serial.println(numRAWX);
uint16_t maxBufferBytes = myGNSS.getMaxFileBufferAvail(); // Get how full the file buffer has been (not how full it is now)
Serial.print(F("The maximum number of bytes which the file buffer has contained is: ")); // It is a fun thing to watch how full the buffer gets
Serial.println(maxBufferBytes);
if (maxBufferBytes > ((fileBufferSize / 5) * 4)) // Warn the user if fileBufferSize was more than 80% full
{
Serial.println(F("Warning: the file buffer has been over 80% full. Some data may have been lost."));
}
lastPrint = millis(); // Update lastPrint
}
if (digitalRead(Button) == HIGH) // Check if the user wants to stop logging
{
uint16_t remainingBytes = myGNSS.fileBufferAvailable(); // Check if there are any bytes remaining in the file buffer
while (remainingBytes > 0) // While there is still data in the file buffer
{
digitalWrite(LED_BUILTIN, HIGH); // Flash LED_BUILTIN while we write to the SD card
uint16_t bytesToWrite = remainingBytes; // Write the remaining bytes to SD card sdWriteSize bytes at a time
if (bytesToWrite > sdWriteSize)
{
bytesToWrite = sdWriteSize;
}
myGNSS.extractFileBufferData(myBuffer, bytesToWrite); // Extract bytesToWrite bytes from the UBX file buffer and put them into myBuffer
myFile.write(myBuffer, bytesToWrite); // Write bytesToWrite bytes from myBuffer to the ubxDataFile on the SD card
remainingBytes -= bytesToWrite; // Decrement remainingBytes
}
digitalWrite(LED_BUILTIN, LOW); // Turn LED_BUILTIN off
myFile.close(); // Close the data file
Serial.println(F("Logging stopped. Freezing..."));
digitalWrite(yellow, LOW);
digitalWrite(green, LOW);
delay(200);
digitalWrite(LED, HIGH);
digitalWrite(yellow, HIGH);
digitalWrite(green, HIGH);
delay(500);
digitalWrite(LED, LOW);
digitalWrite(yellow, LOW);
digitalWrite(green, LOW);
delay(500);
digitalWrite(LED, HIGH);
digitalWrite(yellow, HIGH);
digitalWrite(green, HIGH);
delay(500);
digitalWrite(LED, LOW);
digitalWrite(yellow, LOW);
digitalWrite(green, LOW);
while(1);// Do nothing more
}
}
the code is writing 1024 bytes into sd card every loop
the gnss module that is sending the data to the esp32 should be working at 7hz
I also have a buffer keeping the data and it looks like the writing speed of the sd card is prettly good since the buffer is not getting full at all
Why do you do this every time you write to the card, rather than once?
This is not a good way to handle millis as it doesn't handle rollover correctly. Better to do as below...
if (millis() - lastPrint > 1000)
now that you mention it, it does look weird. thanks for the letting me know ill do some changes
damn, although the changes a made did affect the quality of the data written in the sd card, it didnt help with the frequency problem. I am thankfull anyway.
maybe its the i2c speed that is blocking the data.
here is a image from serial monitor at 7hz:
and here its at 5hz:
I should be receiving way more RAWX data, it did happen before, that time a fixed it by soldering a shorter and better wire as i2c connection.
Can you show a schematic of your setup? Are you using pull up resistors?
The maximum speed of the ESP32's I2C module is 4Mhz.
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2c.html
The bottleneck is probably the SD card.
do you mean the actual SD card? or the code for the SD card?
I am using a sandisk ultra 32GB, formated exfat
maybe the SPI speed? mine is set to 12mhz, I know that esp32 is capable of reaching 80 mhz, but for some reason 12 mhz is the max I was able to set without sd card fail to initialize
void initSDCard() {
uint32_t t = millis();
// Initialize at the highest speed supported by the board that is
// not over 50 MHz. Try a lower speed if SPI errors occur.
if (!sd.begin(SD_CHIP_SELECT_PIN, SD_SCK_MHZ(12))) {
Serial.println("sd.begin failed");
return;
}
t = millis() - t;
cardSize = sd.card()->sectorCount();
if (cardSize == 0) {
Serial.println("cardSize failed");
return;
}
Serial.print(F("\ninit time: "));
Serial.print(t);
Serial.println(" ms");
}
If you are still opening the SD file, writing a bit of data, then closing it again, STOP DOING THAT. That slows I/O to a crawl and vastly increases the SD card error rate.
Open the file once in setup() and close it again when you are all done collecting data. During long term data collection, update file pointers and protect yourself from power failures by calling SD.flush() every hour or so.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.