I am creating a load of 2.5A through high wattage resistors. I am driving it using a N channel MOSFET (IRL2910). I have a current shunt (0 - 3A, 0 - 75mA) in series with the load so I can monitor the current it is using. I would like to read the 0 - 75mA from the current shunt but it is quite noisy as expected due to the on/off of the FET. I have used a RC low pass filter but I cannot take a steady reading in Arduino even if I take 200 readings and average them out! Any ideas would be most appreciated, thanks.
The current shunt is essentially a small resistance of 0.025 ohms.
0.025ohms x 3amps=0.075 volts full scale. I am measuring across this small resistance. As PWM is controlling the current through a N channel mosfet, the voltage I am measuring across the shunt is quite noisy. This is reflected in the ADC being read into the arduino and being displayed on an LCD. The readings are unstable.
Filtering a PWM signal can be done with something like this
Or even without the transistor you should be able to remove the ripple sufficiently to take average readings, and you won't need to tweak it at all. All you will have to do is take the voltage drop of the diode into account.
Yes, I would like to measure the current and read it into ADC and then dispay the current measurement on a LCD. The purpose is to measure vehicle damper current. The ACS712 looks interesting. Can't quite make out from the datasheet if the ACS712 can handle a 3A load? Is there a possiblility that it also will try to follow that same profile of the PWM signal? Or is it likely to average it out and give a stable DC output?
void fReadCurrent( void * parameter )
{
float ADbits = 4096.0f;
float ref_voltage = 3.3f;
float offSET = .0f;
uint64_t TimePastKalman = esp_timer_get_time(); // used by the Kalman filter UpdateProcessNoise, time since last kalman calculation
SimpleKalmanFilter KF_I( 1.0f, 1.0f, .01f );
float mA = 0.0f;
int printCount = 0;
const float mVperAmp = 100.0f;
float adcValue = 0;
float Voltage = 0;
float Power = 0.0;
String powerInfo = "";
powerInfo.reserve( 150 );
while ( !MQTTclient.connected() )
{
vTaskDelay( 250 );
}
TickType_t xLastWakeTime = xTaskGetTickCount();
const TickType_t xFrequency = 1000; //delay for mS
for (;;)
{
adc1_get_raw(ADC1_CHANNEL_3); // read once discard reading
adcValue = ( (float)adc1_get_raw(ADC1_CHANNEL_3) );
//log_i( "adcValue I = %f", adcValue );
Voltage = ( (adcValue * ref_voltage) / ADbits ) + offSET; // Gets you mV
mA = Voltage / mVperAmp; // get amps
KF_I.setProcessNoise( (esp_timer_get_time() - TimePastKalman) / 1000000.0f ); //get time, in microsecods, since last readings
mA = KF_I.updateEstimate( mA ); // apply simple Kalman filter
TimePastKalman = esp_timer_get_time(); // time of update complete
printCount++;
if ( printCount == 60 )
{
xSemaphoreTake( sema_CalculatedVoltage, portMAX_DELAY);
Power = CalculatedVoltage * mA;
//log_i( "Voltage=%f mA=%f Power=%f", CalculatedVoltage, mA, Power );
printCount = 0;
powerInfo.concat( String(CalculatedVoltage, 2) );
xSemaphoreGive( sema_CalculatedVoltage );
powerInfo.concat( ",");
powerInfo.concat( String(mA, 2) );
powerInfo.concat( ",");
powerInfo.concat( String(Power, 4) );
xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
MQTTclient.publish( topicPower, powerInfo.c_str() );
xSemaphoreGive( sema_MQTT_KeepAlive );
powerInfo = "";
}
xLastWakeTime = xTaskGetTickCount();
vTaskDelayUntil( &xLastWakeTime, xFrequency );
}
vTaskDelete( NULL );
} //void fReadCurrent( void * parameter )
Code to read the current sensor and uses a Kalman filter. Code is written for an ESP32 running under freeRTOS, the ESP32's built in OS. freeRTOS is great for a state machine or multi-threading or multi-processing.
Thanks ldahowalker, have you ever used a ACS712? Just wondering if it's worth giving one a try? I think it's got to be an improvement of what I currently (pardon the pun) have?
I see. If I try it without the software filtering, do you think I will get a clean enough signal to read into a ADC? Just want the ripple effect minimsed.