[C.CC USERS] ADC Function Broken

Matt Jadud matt at jadud.com
Thu Aug 9 14:24:19 BST 2012


Hi Brent,

On Wed, Aug 8, 2012 at 4:37 PM, Brent Snyder <blizzardwater at yahoo.com> wrote:
> I became interested in using Occam-pi because I need to perform calculations
> (short time fourier transforms) while simultaneously taking analog
> measurements on my arduino.  So far, I have not been able to get the adc
> function to work (I just get a deadlock error).  Should I start looking into
> using timed interrupts again to take measurements or has anyone solved this
> problem?  If you have written an adc function for yourself that works with
> Plumbing, that would be most helpful.

Could you post your code? That would help. A Github gist would work,
too (or Pastebin, or whatever).

If you're getting a deadlock, it may be because one of your processes
is not running forever. It is common, when writing occam-pi programs
(especially for the Arduino) to write code that always runs.
Certainly, the Plumbing libraries contain many processes with infinite
loops.

PROC main ()
  CHAN SIGNAL request:
  CHAN INT response:
  PAR
    adc (A0, VCC, request?, response!)
    WHILE TRUE
      INT value:
      SEQ
        -- Tell the ADC you want to do a reading
        request ! SIGNAL
        -- Read the response from the ADC
        result ? value
        -- Do something with the value
        value := value + 1
:

If you only pin the ADC once, then your program will deadlock, because
adc() is waiting for another request. Every time you engage in a
channel communication (either a ! or a ?) the scheduler takes a loop
around to see if anyone else would like to execute. Like in Google's
Go (and other CSP-based languages), the channel communications become
explicit synchronization points between the processes.

Do please ask questions here if you continue to get stuck in any way.
When you are in a SEQ block, occam-pi is not all that different from
other sequential languages (C, Python, etc.) in terms of execution.
However, it is a fundamentally parallel language, and when you're
using PAR, you suddenly have to think in terms of process networks and
a scheduler that lives underneath everything you write.

FWIW, we used to implement ADC in terms of interrupts... but, that was
problematic. One thing we cannot do (with the wait.for.interrupt()
foreign function) is have multiple parallel processes wake up on a
single external interrupt. Therefore, if you wrote a program that used
ADC on more than one pin, we would crash the AVR... put simply, we
ended up registering multiple interrupt handlers on a single vector,
and reset the ADC... sometimes in the middle of a conversion. It was
bad.

(It is on the long-term "to do" list to look at enabling support for
waking multiple occam-pi processes on a single AVR interrupt, but it
adds machinery to the VM that takes up flash and RAM. Hence, we did
not do that in the first instance.)

Finally, a word of warning: you are running a bytecode-interpreted
language on the AVR. We take a 16MHz processor and turn it into a...
well, perhaps a 1MHz processor. The context switch times are very
fast, but we pay a real penalty on straight-line code (when compared
to C that has been natively compiled). I do not know if the FFT will
run as fast as you want, and you may find yourself wanting to have the
FFI be implemented natively in C.

In short, as you explore this, please use us as a resource---if our
tools can make things easier for you, we want to see you be
successful.

Cheers,
Matt



More information about the users mailing list