I am successfully running arduino reading 5 EMG analog sensor inputs off of a differential amplifier and driving 5 servos. To improve the signal quality, I want to post-process (rectify, low pass filter, integrate) in my PC before passing to the arduino.
I have the post-processed waveform data in Excel as a time/voltage table. I have no clue how to send this data back out of the PC as an analog voltage to the analog ports of the arduino. Any way the PC can do that without external hardware?
Thanks Paul, that makes sense. Yes they are numerical values of volts. I am testing with the serial port and can talk to the board and get the correct values back using the serial monitor window. Baby step #1
The part I still don't understand is how to stream the 6,000 voltage values in excel to the COM7 serial port on the PC side. Am I going to have to break out Visual Basic or something? Couldn't find any examples like that.
You'll need some application that can read Excel data, and write to the Serial port.
That application can be written in Visual Basic, Visual C++, or C#.
But, I'm not clear how the sensor data you are reading, from the EMG sensors, the post-processing on the PC, and the spreadsheet contents all relate.
Are you collecting data, and then planning on playing it back later? Or is the sensor data supposed to be 'real time' data being processed on the PC before driving the servos?
At this time it is stored on the PC. We digitize and capture the output from a differential amplifier for each EMG channel. The data is stored in an excel spread sheet as (time, millivolt) data pairs. We have to invert, filter and integrate the RMS waveform before we can use it. After processing, we have a data pair each msec for each sensor which produces pretty accurate voltage curves. We can look at it graphically on the PC screen, but don't know how to put it back out to the arduino for control of the servos. I will have to throw away some data as we are only reading the analogPins every 15 msec.
I understand the concept now. I think I can dig up a copy of Visual Basic. I will just have to figure out how to increment that data out to the COM port. I was hoping there was an easier way!
Future goal is realtime conditioning in hardware prior to hitting the arduino. Thanks again for the insight.
Just make sure you really understand the way analogwrite() works.
Its a PWM signal, NOT a "real analog voltage". So if your application needs a real voltage using the PWM signal from analogWrite() will not work.
It is possible to smooth the PWM signal to some degree with a capacitor but if you need an accurate voltage this might not be sufficient.
Another approach is to use an external DAC IC.
By the way, if you put your values in an ordinary txt file on value pr. line, GoBetwino can read the file and send the values to Arduino for you, but depending on how fast you need that done it might be too slow.
Thanks MikMo! I need some help with the GoBetwino calls from Arduino. I have kluged together code from your sample and tried to add my own parts. The GoBetwino code is returning the correct value from my data file, such as 534, but I can't figure out how to assign it to an integer value. Here is my code:
#include <Servo.h>
int serInLen=25;
int val;
char serInString[25];
Servo myservo;
void setup() // run once, when the sketch starts
{
Serial.begin(9600);
delay(3000);
myservo.attach(9);
}
void loop() // run over and over again until out of data
{
char buffer[5];
int lineNr=0;
// asking Gobetwino to read line nr. 1 - 1000 from file
for(lineNr=1;lineNr<=1000;lineNr++) { //number of lines to read
Serial.print("#S|EMGDATA1|[");
Serial.print(itoa((lineNr), buffer, 10)); //convert interger to string
Serial.println("]#"); // Wait for answer from Gobetwino and convert the returned answer to an integer
// readSerialString (serInString, 5000); //call to readSerialString routine
val = Serial.read();
val = map(val, 0, 1023, 0, 179);
myservo.write(val);
delay(5000);
}
}
void readSerialString (char *strArray,long timeOut) {
// Wait up to timeOut miliseconds for data to arrive at the serial port, then read the data and put it in the char array strArray
long startTime=millis();
int i;
while (!Serial.available()) {
if (millis()-startTime >= timeOut) {
return;
}
}
while (Serial.available() && i < serInLen) {
strArray[i] = Serial.read();
i++;
}
}