I am working on a project to receive sine wave from signal generator. I want to get output which shows a full sine wave on serial plotter. Let's say if the input signal is 10hz at 2.0V pk to pk. I am not getting negative amplitude of the wave in Arduino. I understand that Arduino caps anything below "0V". I have tried using dc offset variable to shift the wave up but all it does is started the wave at the value set for offset and caps the values under that.
int gain = 10;
float offset = 2.5;
unsigned long startTime;
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// Set the start time:
startTime = millis();
}
void loop() {
// Check if 20 seconds have passed:
if (millis() - startTime >= 10000) {
// Exit the loop after 10 seconds:
return;
}
//
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Calculate the voltage based on the raw sensor value:
float voltage = (sensorValue * 5.0 / 1023.0);
// Apply the AC-coupled amplifier:
float vout = (voltage - offset) * gain;
// Shift the signal up and down using an op amp configuration:
float vout_shifted = (vout * 2.0) - 2.5;
// Print the voltage amplitude to the serial plotter:
Serial.print(vout_shifted, 3);
Serial.println(" V");
delay(10);
}
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
//using 3.3V reference to get negative values
voltage = voltage - 3.3 ;
// print out the value you read:
Serial.println(voltage);
delay(20);
}
This has helped to get a full wave and i am using the -3.3V to shift the wave for "better" visualisation.
Please let me know if this solution is good.
void setup() {
Serial.begin(115200);
}
void loop() {
static unsigned long startTimestartTime = millis();
// Check if 10 seconds have passed: //warm time?
while (millis() - startTime < 10000);
// Calculate the voltage based on the raw sensor value:
float voltage = float(analogRead(A0) - 512) * 5.0 / 1024.0;
// Print the voltage amplitude to the serial plotter:
Serial.print(voltage, 3);
Serial.println(" V");
delay(10);
}
amritm-2k
Your sketch does work if you do actually have a 2.5V offset on your signal.
However your use of a low Baud rate and the 10ms delay means the output doesn't look very sinusoidal.
I have tried subracting just 512 from raw value. The output signal still does not show a full sine wave. One way I have tried is that I have put one pin at a0 and other pin from signal generator to 3.3V instead of gnd. This helped me to receive the sort of DC offset. In my code I am subtracting the dc offset (3.3) from raw value.
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
//using 3.3V reference to get negative values
voltage = voltage - 3.3 ;
// print out the value you read:
Serial.println(voltage);
delay(20);
}
With that delay you take snapshots of the sine wave, 20ms apart.
You should be sampling as fast as you can, so remove that delay.
Try printing in raw A/D values. Serial.println(analogRead(A0)); // the only line in loop...
Leo..
Why are you not doing this properly like the diagram in post#3?
That is simple and will give you a true mid range offset, well within the tolerance of the two 100K resistors.
Here is a simple trick to get the A/D to sample faster. Add this line to your setup function, it speeds up the A/D clock by changing the value of the prescale divider.
Pre scaler division for about 36K sps (samples per second) for A/D clock
'''
// set up fast sampling mode
ADCSRA = (ADCSRA & 0xf8) | 0x04; // set 16 times division