Shop OBEX P1 Docs P2 Docs Learn Events
Sharing objects between cogs — Parallax Forums

Sharing objects between cogs

Example: I have an ADC object. I want to send the reading over the serial port. And use the same reading in a control loop. The control loop and serial port will run on different cogs because I can't afford delays added to the control loop because of serial activity.

The ADC object hides the calibration aspects of using the P2 ADC. It does Vcc/Gnd calibration at startup. The necessary calibration data and code is stored in the object so the user need not be concerned about it. Just start the object adc1.start(pin) and read a calibrated measurement in mV when desired. adc1.mv()

I would prefer most of the code to be in C, but I can use Spin2 if necessary.

  1. If the code for both cogs is in the same file, I think it would work. It's not ideal from a code management standpoint because the control loop code will be changed out for different applications while the serial interface code remains the same.

  2. Control loop as top file with ADC objects in control object. I could have the control loop feed the data to the serial code. The control loop would spend unnecessary time calculating measurements that the serial thread might not even use. There would be a lot of boilerplate code in the control thread writing ADC measurements into registers contained in the serial port object.

  3. Control loop as top file with ADC objects in serial object. The serial object is written in C. If it was written in spin this might be ideal. Lots of pass-trough boilerplate code in the serial object, but I think that would be fine.

  4. Serial code as top file. The serial code can call pass-through functions on the control code. If I understand correctly I can call a function on the control object that calls a function on the ADC object and all that will run on the serial cog. Also not ideal from a code management standpoint because it is necessary to change the control object when building for a different application.

  5. I could make two copies of the ADC object and run them both on the same pin. That is not ideal because they will have different calibration values. Maybe not enough to matter, but it just seems wrong to send different data to the user / logfile than is being used for the control system.

  6. Design the ADC object for multithreaded use. I would need 64x6 longs of global memory to store the ADC states and calibration. How to allocate global memory? This might actually be a good solution because the ADC calibration can be managed as data. Some ADC inputs have voltage dividers and are not calibrated to 0-3300mV.

Comments

  • roglohrogloh Posts: 5,786
    edited 2022-05-21 23:46

    You could possibly use a log buffer FIFO in HUBRAM to write the latest ADC data into from your control loop COG and have the serial COG just polling the head pointer and tracking its tail pointer and serially outputting any new data as it arrives. The log buffer size needs to be suitably sized to deal with serlal output latencies. Setup the buffer area and head/tail pointers and pass their addresses in as pointer arguments at COG start time.

    @SaucySoliton said:
    6. Design the ADC object for multithreaded use. I would need 64x6 longs of global memory to store the ADC states and calibration. How to allocate global memory? This might actually be a good solution because the ADC calibration can be managed as data. Some ADC inputs have voltage dividers and are not calibrated to 0-3300mV.

    Unfortunately P2's SPIN has no dynamic automatic global memory allocation capabilities inherently so just let the user deal with it via buffer pointer arguments that they need to manage in their own application. That's what I tend do in my drivers to workaround it. It makes it slightly harder on the user, yes, but gets around the issue at least. Memory is statically allocated at compile time.

  • It seems like it my be worth exposing the base address of your calibration values so that after the ADC pin is setup and calibrated in one cog, the address of the cal values could be passed to another. Am I over simplifying?

  • pik33pik33 Posts: 2,366

    The simplest way is creating an array in the main program

    long adcval_addr
    long adcvalues[whatever_count_you_need]
    adcval_addr=@adcvalues[0]
    

    then pass adcval_addr to the ADC cog and let it do the measurement in the closed loop and save what it measured to adcvalues[]

    Now, every cog can read long[adcval_addr+offset] whenever it wants to. It is read only thing, so no conflicts to solve.

  • Thank you all for your input.

    I think that I will make a multi-channel multi-instance ADC object. That should make things easiest.

Sign In or Register to comment.