Since the circuit of this project assembled successfully, this week, we were mainly focusing on audio sample process on Arduino board the data transmission between Arduino board and computer through serial port. We firstly focused on the sample program. Typically, function analogRead () could be used to sample the analogue signal in Arduino language. However, analogRead could only provide the sample rate 9600 Hz. It was far low to the common sample rate 44.1KHz. To make a higher sample rate, we need to reset the ADC in Arduino board and bypass the function analogRead. In Arduino, ADC takes 13 clock cycles to read a new analog value (25 for the first data point). As a result, we could set the clock of ADC to 500000 Hz to make the sample rate 500/13=~38.5KHz which was near to 44.1KHz which is the common sample rate. To reset the clock of ADC, we needed to set the prescaler as 32. It could devide down the processor clock speed which is 16MHz set the frequency of ADC as 16MHZ/32 = 500KHz.
As for the transmission program, according to some researches, we finally decided to use c++/cli language to code the transmission program. c++/cli contains some powerful class functions for serial port transmission. Otherwise, we need to call API functions to design a new serial port class. This is a complicated task for a three-member group and it will increase the fail risk for the whole project. Meanwhile, we could still use c++ language to write the program for audio processing and matching part. There are some excellent examples and references on the NETfreamwork official website.
When we working in this part, we found the instant transport rate of serial port cannot reach sample rate even it reach the maximum ordinary baud rate which is 115200. Meanwhile the Arduino board did not have enough storage space for the sampled data. According to the discussion, we decided to continue the original plan. If the sample rate has a big impact to the recognition process, we will let the system only recognition the audio with around 1000 Hz as the sample rate of our system is around 2500 Hz.
After we finished the program for this part, when we tested it, we found that the quantity of data that computer got cannot match that Arduino board sent. It was always larger than the required number. According to some surveys, the reason exposed that the rate of computer reading the data was much larger than the Arduino board writing rate. To solve this problem, we set a condition to ensure that computer read each data after the Arduino board has wrote each. The core code in this part could be seen:
c++/cli code:
static void Read()
{
String^ name;
StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase;
// Create a new SerialPort object with default settings.
_serialPort = gcnew SerialPort();
// Allow the user to set the appropriate properties.
_serialPort->PortName = "COM3";//SetPortName(_serialPort->PortName);
_serialPort->BaudRate = 115200; //SetPortBaudRate(_serialPort->BaudRate);
//_serialPort->Parity = SetPortParity(_serialPort->Parity);
//_serialPort->DataBits = SetPortDataBits(_serialPort->DataBits);
//_serialPort->StopBits = SetPortStopBits(_serialPort->StopBits);
//_serialPort->Handshake = SetPortHandshake(_serialPort->Handshake);
_serialPort->ReadTimeout = 0; //ms
_serialPort->WriteTimeout = 500;
_serialPort->ReadBufferSize = 1048576;
_serialPort->Open();
_continue = true;
int a = 0;
ofstream fout("sample.txt");
int x = 0;
Console::WriteLine("Loading...");
_serialPort->WriteLine("0");
while (_continue&&x <= 23000)
{
try
{
if (_serialPort->BytesToRead != a){
a = _serialPort->BytesToRead;
String^message = _serialPort->ReadLine();
MarshalString(message, mes);
fout << mes << endl;
//Console::WriteLine(message);
x = x + 1;
}
}
catch (TimeoutException ^) {}
}
_serialPort->DiscardInBuffer();
_serialPort->DiscardOutBuffer();
_serialPort->Close();
fout.close();
cout << "finish" << endl;
//cin >> x;
}
Where function MarshalString was used to convert the system string into std string.
Arduino code:
int start;
String serialString="";
boolean readCompleted = false;
boolean sendFlag=false;
void setup() {
//clear ADCSRA and ADCSRB registers
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
Serial.begin(115200);
serialString.reserve(200);
}
void loop() {
int counter=0;
if(Serial.available()>0)
{
sendFlag=true;
char inChar=(char)Serial.read();
if(inChar!='\n')
{
serialString += inChar;
}
else{
sendFlag=true;
}
}
if(sendFlag)
{
start=millis();
while(counter<=23000){
Serial.println(ADCH);
counter=counter+1;}
sendFlag=false;
}
}
Summary: In this week, we designed the arduino sample program and the serial port transmission program. Although the sample rate cannot reach the common sample rate 44.1KHz, the whole system could record the audio data with a low frequency successfully. However, there are some error data points appeared in the frond of data stream. Next week, we need to go trough this problem and then focus on the core part: audio recognition program.
As for the transmission program, according to some researches, we finally decided to use c++/cli language to code the transmission program. c++/cli contains some powerful class functions for serial port transmission. Otherwise, we need to call API functions to design a new serial port class. This is a complicated task for a three-member group and it will increase the fail risk for the whole project. Meanwhile, we could still use c++ language to write the program for audio processing and matching part. There are some excellent examples and references on the NETfreamwork official website.
When we working in this part, we found the instant transport rate of serial port cannot reach sample rate even it reach the maximum ordinary baud rate which is 115200. Meanwhile the Arduino board did not have enough storage space for the sampled data. According to the discussion, we decided to continue the original plan. If the sample rate has a big impact to the recognition process, we will let the system only recognition the audio with around 1000 Hz as the sample rate of our system is around 2500 Hz.
After we finished the program for this part, when we tested it, we found that the quantity of data that computer got cannot match that Arduino board sent. It was always larger than the required number. According to some surveys, the reason exposed that the rate of computer reading the data was much larger than the Arduino board writing rate. To solve this problem, we set a condition to ensure that computer read each data after the Arduino board has wrote each. The core code in this part could be seen:
c++/cli code:
static void Read()
{
String^ name;
StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase;
// Create a new SerialPort object with default settings.
_serialPort = gcnew SerialPort();
// Allow the user to set the appropriate properties.
_serialPort->PortName = "COM3";//SetPortName(_serialPort->PortName);
_serialPort->BaudRate = 115200; //SetPortBaudRate(_serialPort->BaudRate);
//_serialPort->Parity = SetPortParity(_serialPort->Parity);
//_serialPort->DataBits = SetPortDataBits(_serialPort->DataBits);
//_serialPort->StopBits = SetPortStopBits(_serialPort->StopBits);
//_serialPort->Handshake = SetPortHandshake(_serialPort->Handshake);
_serialPort->ReadTimeout = 0; //ms
_serialPort->WriteTimeout = 500;
_serialPort->ReadBufferSize = 1048576;
_serialPort->Open();
_continue = true;
int a = 0;
ofstream fout("sample.txt");
int x = 0;
Console::WriteLine("Loading...");
_serialPort->WriteLine("0");
while (_continue&&x <= 23000)
{
try
{
if (_serialPort->BytesToRead != a){
a = _serialPort->BytesToRead;
String^message = _serialPort->ReadLine();
MarshalString(message, mes);
fout << mes << endl;
//Console::WriteLine(message);
x = x + 1;
}
}
catch (TimeoutException ^) {}
}
_serialPort->DiscardInBuffer();
_serialPort->DiscardOutBuffer();
_serialPort->Close();
fout.close();
cout << "finish" << endl;
//cin >> x;
}
Where function MarshalString was used to convert the system string into std string.
Arduino code:
int start;
String serialString="";
boolean readCompleted = false;
boolean sendFlag=false;
void setup() {
//clear ADCSRA and ADCSRB registers
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
Serial.begin(115200);
serialString.reserve(200);
}
void loop() {
int counter=0;
if(Serial.available()>0)
{
sendFlag=true;
char inChar=(char)Serial.read();
if(inChar!='\n')
{
serialString += inChar;
}
else{
sendFlag=true;
}
}
if(sendFlag)
{
start=millis();
while(counter<=23000){
Serial.println(ADCH);
counter=counter+1;}
sendFlag=false;
}
}
Summary: In this week, we designed the arduino sample program and the serial port transmission program. Although the sample rate cannot reach the common sample rate 44.1KHz, the whole system could record the audio data with a low frequency successfully. However, there are some error data points appeared in the frond of data stream. Next week, we need to go trough this problem and then focus on the core part: audio recognition program.
没有评论:
发表评论