Should work, but does not
Beavis3215
Posts: 229
in Propeller 1
/* GFI for safety extension cord */ #include "simpletools.h" #include "adcDCpropab.h" void measure_imax(); void trip_breaker(); volatile float i; volatile float imax; int main() // Main function runs 7 segment LED's in cog 0 { cog_run(measure_imax,128); // Start littlebird measurments cog_run(trip_breaker,128); // Start circuit breaker control adc_init(21, 20, 19, 18); set_directions(15, 0, 0b1111111111111111); // pins 15 through 0 are outputs int d[] = {0b1110111, 0b1000100, 0b1101011, 0b1101110, 0b1011100, //digits 0 through 9 0b0111110, 0b0011111, 0b1100100, 0b1111111, 0b1111100}; pause(1000); // Let hardware boot up while(1) { float amps = ((imax - 2.7)) * 3; // Scale Littlebird voltage to mean amps int a = (int) amps; // intger part of amps float b = (10 * (amps - a)); int c = (int)b; // fractional part of amps //print("%f, %d, %d\n", imax, a, c); set_outputs(15, 9, d[c]); // c is the decimal value set_output(1,1); // pin 1 is the decimal digit driver pause(8); set_output(1,0); set_outputs(15, 9, d[a]); // a is the integer value set_output(2,1); // pin 2 is the integer digit driver pause(8); set_output(2,0); } } void measure_imax() // Runs in a different cog { while(1) { for (int sample = 0; sample <= 60; sample++) // Littlebird samples per loop { i = adc_volts(2); // i is instantaeous Littlebird voltage // if (i < 2.7) // { // float temp = 2.7 - i; // i = temp + 2.7; // } // float j = adc_volts(2); // Invert samples below 2.7 volts if (j < 2.7) // to the same value above 2.7 volts { // float temp = 2.7 - j; // j = temp + 2.7; // } // if (j > i) { i = j; } } imax = i; // Stores maximum voltage sample } } //2.75v reference voltage Littlebird output of .33volts/Amp void trip_breaker() //Amps = (i - 2.75) x 3 { if (i < 2.9) { set_output(0,1); //Turn on breaker if current under .45 amps } while(1) { print("%f, %d, %d\n", imax); if (i > 2.9) { set_output(0,0); //Turn off breaker and lock out if over .45 amps } } }
Why cant trip_breaker see "I"?
Comments
It may also be possible that your set_output(0,0) is immediately undone by set_output(0,1) because i drops below 2.9 immediately after the set_output(0,0). I don't know your setup, so I can really tell you if that's the case. Maybe you could describe the circuit you're controlling.
Ultimately, it seems like you should move the measure_imax code into the trip_breaker function. I don't see a reason to have them in two difference cogs. This way, trip_breaker will be able to look at every sample that is measured.
all DIRAs and OUTAs from different COGs are 'or'-ed together.
If one COG declares it as output, it is OUTPUT independent what other COGs think about it.
And if one COG has it declared as output and set high, no other COG can change that.
Enjoy!
Mike
Here "throw breaker" is in void measure_imax. This code works
Here "throw_breaker" is in its own cog and does not work. The breaker will turn on with set_output(0,1), but seems like the condition is never met for the breaker to turn off. If the condition is met, then set_output(0,0) is not functioning. What is the functional difference between the two methods. How can I make it work in a separate cog. Later throw_breaker will have more conditions by which to control the breaker, and will need to have its own cog if I understand the last response correctly.
- define the float i as static instead of volatile.
- Use integer for i instead of float. There may be a problem with the float library used in different cogs. Just store the voltage in mV to get a good resolution: Then the throw_breaker cog does not need float calculations:
If it's not really necessary then don't use floats with microcontrollers, especially not if there is not float hardware.
Andy
So I made the recommended changes, and for some reason the main loop cant see imax from measure_imax.
I ran in terminal to verify that imax = 0, and a and b are negative numbers.
Apparently I don't understand all of the rules yet, any ideas?