Send data packs to database

Hello everyone!

I use Ad8242 ECG sensor and ESP32. In my project im sending the data to database and next with php code i get data from database and show the chart in website. The problem is that i must use the frequency 50Hz, but i cand send so many httprequests to database. I'm thinking about is there an option to save the data temporary to data packets and next to send this data to database. I was trying to save the data by simple array but when i sent data i was reciving only 0 or id of data.

the probability of 50Hz to a database working is doubtful unless it is on a local network
rather than attempting to transmit 50 times/second try reducing traffic by transmitting 5 samples every tenth of a second
your chart should still update in near real time

we had a similar application recently collecting data from a sensor every 20mSec (using timer interrupts) which was saved into a ring buffer, formed into a frame and transmitted over BLE to a smart phone every second

I know that this is the problem that the database could have problems.

As i told i tried to send the data as array but couldnt make anything :frowning:

Could you please send me your code for your project with ring buffer?

the example mentioned in post #1 was was a commercial product implemented on a PIC24 processor
however, if you do aa web search for arduino ring buffer you will get plenty of links

could you download the array code which failed?

I could update the code at the evening. Thanks anyway :smiley:

The array function is from stackoverflow

https://stackoverflow.com/questions/63743592/how-to-send-data-packets-to-mysql

#include <WiFi.h>
#include <HTTPClient.h>

bool takeAnalogReadings(uint16_t* p_numReadings = nullptr, uint16_t** p_analogVals = nullptr);

void setup() {

Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println(“Connecting”);
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());

}

void loop() {

if(WiFi.status()== WL_CONNECTED){
uint16_t numReadings;
uint16_t* analogVals;
bool readingsDone = takeAnalogReadings(&numReadings, &analogVals);
if (readingsDone)
{
// Let’s print them all out!
Serial.print("numReadings = “); Serial.println(numReadings);
Serial.print(“analogVals = [”);
for (uint16_t i=0; i<numReadings; i++)
{
if (i!=0)
{
Serial.print(”, ");
}
Serial.print(analogVals*);*

  • }*

  • Serial.println("]");*

  • }*

  • HTTPClient http;*

  • http.begin(serverName);*

  • http.addHeader(“Content-Type”, “application/x-www-form-urlencoded”);*

String httpRequestData = “api_key=” + apiKeyValue + “&value1=” + String(analogVals*);
_
Serial.print("httpRequestData: ");_
_
Serial.println(httpRequestData);_
_
int httpResponseCode = http.POST(httpRequestData);*_

* if (httpResponseCode>0) {*
* Serial.print("HTTP Response code: ");*
* Serial.println(httpResponseCode);*
* }*
* else {*
* Serial.print("Error code: ");*
* Serial.println(httpResponseCode);*
* }*
* // Free resources*
* http.end();*
* }*
* else {*
* Serial.println(“WiFi Disconnected”);*
* }*
* delay(1000);*
}
bool takeAnalogReadings(uint16_t* p_numReadings, uint16_t** p_analogVals)
{
* static const uint16_t NUM_READINGS = 20;
static uint16_t i = 0; // index*

* static uint16_t analogVals[NUM_READINGS];
const uint32_t SAMPLE_PD = 50; // ms; sample period (how often to take a new sample)
static uint32_t tStart = millis(); // ms; start time*

* bool bufferIsFull = false; // set to true each time NUM_READINGS have been taken*
* // Only take a reading once per SAMPLE_PD*
* uint32_t tNow = millis(); // ms; time now*
* if (tNow - tStart >= SAMPLE_PD)
_
{_
_
//Serial.print("taking sample num "); Serial.println(i + 1);_
tStart += SAMPLE_PD; // reset start time to take next sample at exactly the correct pd*

_ analogVals = analogRead(A0);
* i++;_
if (i >= NUM_READINGS)
_ {
bufferIsFull = true;
i = 0; // reset to beginning of array, so you don’t try to save readings outside of the bounds of the array*
* }
}
// Assign the user-passed-in pointers so that the user can retrieve the data if they so desire to do it this way*
* if (p_numReadings != nullptr)*
* {
*p_numReadings = NUM_READINGS;
}_
if (p_analogVals != nullptr)
_ {
*p_analogVals = analogVals;
}
return bufferIsFull;
}*_

mkul:
Could you please send me your code for your project with ring buffer

this is an example where a timer interrupt service routine saves a record into a ring buffer every 20mSec
the main loop() then extracts the records and checks for sequence errors

// 20mSec timer interrupt - write record into ring buffer

// adapted from https://www.instructables.com/id/Arduino-Timer-Interrupts/

//timer1 will interrupt at every 20msec 50times/second   // pin 13

// test structure
struct TESTrecord {
    unsigned short int seq;
    short int temperature;
}
testRecord;

// ring buffer and indexes
volatile byte  data[sizeof(testRecord)*100+100];     // dual buffer for MEMS data
volatile int inData=0,  outData=0, inDataCount=0;                               // index into buffers

//timer1 interrupt called every 20mSec
ISR(TIMER1_COMPA_vect){
      // increment sequence number and add structure to ring buffer
      testRecord.seq++;
      memcpy((byte*) &data[inData], (byte*)&testRecord, sizeof(testRecord));;
      // increment index to ring buffer and if at end reset to start
      if((inData+=sizeof(testRecord))>=sizeof(testRecord)*100) inData=0;
      // increment count of records in buffer
      inDataCount++;
}

unsigned long int time=millis();
void loop(){
  // check if  records in ring buffer - if so read next record
  while(inDataCount) {    
      // used to check sequence numbers of records in buffer    and error count 
      static unsigned short int seqCheck=0, errors=0;       
      // if ring buffer overflow display message and reset
      if(inDataCount>100) {
         Serial.println("ring buffer overflow");
         inData=0,  outData=0, inDataCount=0, seqCheck=0,  testRecord.seq=0;
         errors++;
         break;
      }
      // read a record from buffer
      struct TESTrecord record;
      memcpy((byte*)&record, (byte*) &data[outData], sizeof(testRecord));;
      // if at end of buffer reset to start and display some data
      if((outData+=sizeof(testRecord))>=sizeof(testRecord)*100) {
           outData=0; Serial.print(" time "); Serial.print(millis()-time); 
           Serial.print(" seqcheck ");Serial.print(seqCheck); 
           Serial.print(" errors ");Serial.println(errors); 
           }
      inDataCount--;            // decrement count of records in buffer
      // check record sequence number - if in error reset and display !
      if(record.seq != ++seqCheck) {
        seqCheck=record.seq;      // reset
        Serial.print('!');
        errors++;
        }
      else Serial.print('*');     // sequence number OK
      }    
  }

void setup(){
  Serial.begin(115200);
  pinMode(13, OUTPUT);
  Serial.println("20mSec timer interrupt - write record into ring buffer");
  cli();//stop interrupts
  //set timer1 interrupt every 20mSec
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 311;// = (16*10^6) / (50*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS12 and CS10 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei();//allow interrupts
  // delay(3000);      // uncomment to force ring buffer overflow
}

a run gives

20mSec timer interrupt - write record into ring buffer
*************************************************************************************************** time 1996 seqcheck 99 errors 0
**************************************************************************************************** time 3993 seqcheck 199 errors 0
**************************************************************************************************** time 5990 seqcheck 299 errors 0
**************************************************************************************************** time 7987 seqcheck 399 errors 0
**************************************************************************************************** time 9984 seqcheck 499 errors 0
**************************************************************************************************** time 11980 seqcheck 599 errors 0
...
**************************************************************************************************** time 537139 seqcheck 26899 errors 0
**************************************************************************************************** time 539136 seqcheck 26999 errors 0
**************************************************************************************************** time 541132 seqcheck 27099 errors 0