My first multicore design with problems
Beavis3215
Posts: 229
in Propeller 1
#include "simpletools.h" #include "adcDCpropab.h" void measure_imax(); volatile float i; volatile float imax; int main() // Main function { cog_run(measure_imax,128); 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}; while(1) { int a = (int) imax; // intger part float b = (10 * (imax - a)); int c = (int)b; // frac part //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() { while(1) { for (int sample = 0; sample <= 100; sample++) { i = adc_volts(2); if (i > 0) { float j = adc_volts(2); if (j > i) { i = j; } } } float imax = i; } }
This program is supposed to use a second cog to take samples of a 60hz voltage and store the max value in imax. The code in cog 0 takes imax and breaks it down into integer and fractional parts, to be displayed on 2) 7 segment leds.
I originally wrote this code in cog 0 and it ran, and gave output, but the sampling was slowed too much by the display routine. I worked through the simple library to write this multi-cog version, but for some reason the output is 0.0. Does
#include "adcDCpropab.h" need to be with the measure_imax function? Is there a mistake I made where the 2 functions don't communicate through the global variables? Please help I am using the WX activity board.
Comments
Looks like the second cog tests for an ADC value of zero and if so calculates j. But the last line which I think posts to the global is outside the zero test. So it will pass the zero value to the first cog for display.
If you haven't already, you might want to have a look at the example in the Learn links.
http://learn.parallax.com/tutorials/language/propeller-c/multicore-approaches/cores-sharing-data
I think it is fine. The code is checking first if 'i' is greater than 0, and if it is read in a new value into variable 'j'. Then 'j' and 'i' are compared to see if 'j' is larger than 'i' in which case 'i' is set to the value of 'j'. At the end of the for loop, imax is set to 'i' which should be the largest value of the loop. However, I am not sure if it is necessary to call 'adc_volts' twice like that. I think only once is needed. And, since there is already an 'imax' global, 'i' seems a bit redundant. I would have declared a local temp value in 'measure_imax". Also, I am not a fan of declaring a variable in a loop since it may get declared over and over or the compiler might just set it to be declared outside of the loop. I would have just declared 'j' before the 'while' loop. But that is just me.
that the function could be fast enough where the device could actually act like a AC voltmeter instrument?
There needs to be a faster stream of imax values or a way to dampen the display.
http://learn.parallax.com/tutorials/language/propeller-c/multicore-approaches/cores-sharing-data
I think that the "if" loop in "measure_imax" is cycling too fast. If i is zero, the loop takes almost no time so it does 100 repeats and gets the same value. Try putting a pause(x) into the loop. Experiment with the value of x, maybe different delays if i is zero and if i is greater than zero.
The other thing in "measure_imax", each time through the loop you are resetting i to adcvolts(2). If in the previous time through the loop j was > i, you set i = j. But the next time through the loop that value of i is thrown away as i is reset to adcvolts(2).
Tom
//added a inCog1 variable to determine if in cog1 or not.
In cog1
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
2.652588, 2, 6
In cog1
2.657471, 2, 6
2.657471, 2, 6
2.657471, 2, 6
2.657471, 2, 6
2.657471, 2, 6
2.657471, 2, 6
2.657471, 2, 6
By increasing the pause in the cog0 loop and adding one in the cog1 loop, the two cogs are more inline. With more adjustment and both could be synced.
// After increase pauses:
2.667236, 2, 6
In cog1
2.678223, 2, 6
2.678223, 2, 6
In cog1
2.668457, 2, 6
In cog1
2.664795, 2, 6
In cog1
2.655029, 2, 6
2.655029, 2, 6
In cog1
2.655029, 2, 6
In cog1
2.648926, 2, 6
// My hacking of your code, but leaving most in place.