/* IVOProp In-Flight Adjustable Propeller Control Uses ACS712 current sensing module to monitor propeller current. Uses SLA-12VDC-SL-C 30 Amp relay module to stop current when limit is reached. 2017-07-06 By Doug Garland Used with Medium IFA IVOProp and Rotax 912ULS NOTE: I currenly have the current sensor connected between the IVOProp switch and ground, so my current readings are always positive. Probably a better setup would be to have the sensor reading one of the lines between the switch and motor. That would allow for completely stopping motor current once a limit is reached. Slight modification of the code would be required to implement that. Use and/or modify at your own risk. */ const int analogIn = A0; //current sensor const int readDelay = 100; //ms between Amp reads const int downTime = 5000; //ms to keep relay off const int ocMax = 3; //max consecutive over-current reads const int RELAY1 = 8; //digital pin 8 const int greenLED = 12; //digital pin 12 const int redLED = 13; //digital pin 13 const double minAmps = 0.5; //threshold to consider circuit active const double maxAmps = 9.0; //prop motor current limit, indicating approaching pitch limits int ocCount = 0; //how many over-current events have occurred double Amps = 0; void setup(){ // Initialize the Arduino data pins for OUTPUT pinMode(greenLED,OUTPUT); pinMode(redLED,OUTPUT); pinMode(RELAY1, OUTPUT); } void loop(){ ocCount = 0; //reset over-current count //read Amps... Amps = getAmps(); //turn on green led if moving; ensure leds off otherwise if(abs(Amps) > minAmps){ digitalWrite(greenLED,HIGH); digitalWrite(redLED,LOW); }else{ digitalWrite(greenLED,LOW); digitalWrite(redLED,LOW); } //check for over-current //if true, do up to ocMax reads to verify while(abs(Amps) > maxAmps && ocCount < ocMax){ ocCount++; //increment consecutive over-current states delay(readDelay); //sleep Amps = getAmps(); } if(ocCount >= ocMax){ //if too many consecutive over-currents digitalWrite(RELAY1,HIGH); //open relay digitalWrite(greenLED,LOW); //green led off digitalWrite(redLED,HIGH); //red led on delay(downTime); //leave open for a bit, then reset //presumably, by now, pilot got the message digitalWrite(RELAY1,LOW); //close relay digitalWrite(redLED,LOW); //red off }else{ digitalWrite(RELAY1,LOW); //ensure circuit closed since no over-current yet delay(readDelay); //sleep } } //function reads from current sensor module //returns Amp value based on average of multiple samples double getAmps(){ int mVperAmp = 100; //use 100 for 20A Module int RawValue = 0; //from analog input int ACSoffset = 2500; //half of 5V int numSamples = 4; //how many readings to average double Voltage = 0; double sampleAmps = 0; for(int x = 0; x < numSamples; x++){ RawValue = analogRead(analogIn); //read current sensor Voltage = (RawValue / 1024.0) * 5000; //Gets you mV sampleAmps += ((Voltage - ACSoffset) / mVperAmp); } return sampleAmps / numSamples; //return the average of the samples }