Audio transmitter

Status
Not open for further replies.

iammb

Member
Hi,
I am working on a project where i want to upload audio files(.wav) to server using GSM. Device should record 10 sec audio files continuously but when controller is free(between writing samples to SD card) it should send AT commands to GSM. I have implemented this using polling method, but in polling i am loosing audio as its not recording when i am sending AT commands. I also tried SerialEvent, it performs better than polling but sometimes SerialEvent function doesn't receive full response from GSM module. Can anyone tell me what can be the best way to handle this where i can prioritize uart in background and making recording as higher priority. I have interfaced GSM with teensy3.5/3.6 over UART(Serial1).
 
I want the device to record continuously and whatever time is left between waiting for queue to fill with audio data and writing samples to sd card, i want to send AT commands over UART.
 
Showing a sample of code would help. serialEvent() is no better than polling - it is just auto polling on any delay() or yield() and between each loop() entry. Though if delay is used that will result in more cause but wasted and lost time otherwise.

If GSM data is being lost - the buffers are not large enough to hold incoming data stream during the lag times of SD write, or other, and can be increased in the CORES files for the UART in use. How large is the incoming GSM string? At what baud?
 
Biggest incoming string coming from GSM is around 50-60 characters. I am using Serial1 at 921600 baud rate and core clock is set to 120Mhz. Code below is part of working code which records wav file and uploads it to FTP. Problem in the code is that recording is not continuous, when i am handling gsm commands it adds up time in recorded wav files.
Code:
char event_response_buffer[512] = {0};
uint32_t event_response_counter = 0;

void loop()
{
  if((!recordInProgress && record_complete))
  {
    recordInProgress = true;
    record_complete = false;
    DEBUG_PRINT(("startRecording"));
    DEBUG_PRINT(("new filename"));
    snprintf(filename, sizeof(filename), "%s%lu.wav", file_name, filenumber);
    DEBUG_PRINT((filename));
    digitalWrite(LED_REC, HIGH);
    Set_Icmt_comment();
    frec = SD.open(filename, FILE_WRITE);
    writeWavHeader();
    SdFile::dateTimeCallback(dateTime);
    if (frec)
    {
      recByteSaved = 0L;
    }
  }
  else if(((queue1.available() >= 2) && (recByteSaved < (SAMPLE_RATE * 2 * 10))))
  {
    memcpy(buffer, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    memcpy(buffer + 256, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    frec.write(buffer, 512);                // write all 512 bytes to the SD card
    recByteSaved += 512;
  }
  else if((recByteSaved >= (SAMPLE_RATE * 2 * 10)))
  {
    DEBUG_PRINT(("stopRecording"));
    writeOutHeader();
    frec.close();
    digitalWrite(LED_REC, LOW);
    recordInProgress = false;
    recording_flag = true;
    record_complete = true;
    if(!first_file_rec)
    {
      DEBUG_PRINT(("transmit flag on!"));
      first_file_rec = true;
      network_check_stage = true;  
    }
    filenumber++;
  }
  else if(network_check_stage)
  {
    network_check_stage = false;
    event_response_counter = 0;
    memset(event_response_buffer,'\0',512);
    DEBUG_PRINT(("network_check_stage"));
    Send_command("AT+CREG?");
  }
  else if ((strstr(event_response_buffer,"+CREG: 0,1")) || (strstr(event_response_buffer,"+CREG: 0,5")))
  {
    gprs_check_stage = true;
    event_response_counter = 0;
    memset(event_response_buffer,'\0',512);
    DEBUG_PRINT(("Network available"));
  }
}

void serialEvent1(void) 
{
  while(Serial1.available() > 0)
  {
    // get the new byte:
    event_response_buffer[event_response_counter] = Serial1.read();
    Serial.print(event_response_buffer[event_response_counter]);
    event_response_counter++;
  }
}
 
Hi,
Can you reduce the baud rate?
Perhaps it might help to draw a timing diagram for all the tasks that have to be done.
 
For transmission of wav file via gsm, first i have to write file to EFS(Encrypted file system) of gsm and then issue AT command to upload file. If i use low baud rate eg:115200, the data transfer takes so much time. For 10 sec audio file 16 kHz sample rate and 313 KB file size if i transfer data from sdcard to EFS via Serial1 it will take around 21sec and with 921600 it will take 2.7sec. This is the reason i chose max baud rate supported by gsm module.
 
Nice not to see delay() used, adding a yield will trigger a call to serialEvent() - or you can just call to serialEvent1(), and it will return when no characters are at hand as written, before any time consuming process or loop begins … SD write or other.

Not seeing a problem with using highest baud rate - just means the characters needed arrive for processing in shorter time, but buffers need to be big enough to handle one or perhaps more messages if they can double up. If only one message in flight at a time then the 64 bytes should be holding it. If more than one then the way the memset(E_R_buffer) is zeroed could be trashing the start of the next message?

For Serial1 in : {Arduino install}\hardware\teensy\avr\cores\teensy4\HardwareSerial1.cpp
these #defines can be increased to give space for the hardware FIFO to buffer more data before it will be lost when not read soon enough.
Code:
#ifndef SERIAL1_TX_BUFFER_SIZE
#define SERIAL1_TX_BUFFER_SIZE     64 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL1_RX_BUFFER_SIZE
#define SERIAL1_RX_BUFFER_SIZE     64 // number of incoming bytes to buffer
 
Whow, did not know, that the Hardware fifo is 64bytes. In former times these have been only 2 bytes. Wanted even to suggest an extra dedicated teensy to handle this. Rts cts? There seems a lot going on in this project. Sampling, write SD, read SD, receive and transmit and what else? I also wonder how long the SD will last with this many writes?
 
Status
Not open for further replies.
Back
Top