"fork" off an analog input

Hi all,

This is my first post so please be kind.

This has probably been asked before but I cant find the specific answer for it...

I'm pretty new to Arduino but been coding C for years, albeit a bit rusty.

I am playing around with an LED Cube I made which works just fine. I've added a pot to an analog input which also works fine. But I'd like to "fork" the reading of the analog input off to another "thread" and call its value at different parts of my code.

Currently every time in my code I need to read the analog value I have to use the line:

sensorValue = analogRead(sensorPin);

Then use the acquired value:

For example : delay(sensorValue);

I am wondering if this analog value could be constantly read in a parallel process and the value called upon when needed...??

Is this possible? Any ideas??

Thanks

analogRead takes around 100 microseconds.
You could have a free-running interrupt-driven analogue reading.

I am wondering if this analog value could be constantly read in a parallel process and the value called upon when needed...??

Probably not necessary

You have not posted your code but if written properly the loop() function will run every couple of milliseconds at the most so you can read the pot very frequently and use sensorValue wherever you need it.

Your program presumably has blocking code in it such as for loops, while loops and delay(). Eliminate them and your problem will be solved.

See Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE for ideas how to do it.

There are ways around it, as suggested, but as to your main question, you can't use fork - the arduino is single threaded.

Psyonic:
I've added a pot to an analog input which also works fine. But I'd like to "fork" the reading of the analog input off to another "thread" and call its value at different parts of my code.

Come at this from the other end.

Have a function that is called regularly to read the analog pin and save the value to a variable.

Elsewhere in your program refer to that variable when you want the latest value.

...R
Several Things at a Time
Planning and Implementing a Program

Thanks for all your replys!
Sorry for not replying sooner, as I said, I'm a noob here and was expecting to get emails whenever I get a reply... I didn't get any emails so I just thought no one had replied! :stuck_out_tongue: :blush:

Ok, so no "fork", fair enough. Thanks wildbill.

It's a simple LED Cube, just for learning purposes. Perhaps I am going about it wrong UKHeliBob, but each "display" on the cube takes some time so 1 scan or loop can take several minuets so putting the analogRead only once is not possible if it is to be used to change the rate of the LEDs being updated.

Also, calling the read just before using the value is very possible, it's currently how I'm doing it, but it just seams like a very inefficient way of writing code.

AWOL, "You could have a free-running interrupt-driven analogue reading." sounds interesting, can you give me any links? (I'll google it to be sure!)

Thanks again guys/gals!

Code is attached
(as you can see, ""sensorValue = analogRead(sensorPin); delay(sensorValue);"" is everywhere! Very annoying!)

_4x4_Cube_Analog.ino (25.1 KB)

Psyonic:
It's a simple LED Cube, just for learning purposes. Perhaps I am going about it wrong UKHeliBob, but each "display" on the cube takes some time so 1 scan or loop can take several minuets so putting the analogRead only once is not possible if it is to be used to change the rate of the LEDs being updated.

Did you study the links provided in reply #2?

I have now...
I see now how it can be achieved. Getting the Arduino to act more like a PLC, scanning and reacting to events WHEN required... Very different way of programming to what I'm used to, but for a micro-controller, very powerful too!!

Thanks!

Perhaps I am going about it wrong UKHeliBob

If you want the program to be responsive to inputs then the way that you are doing it is wrong.

The principle should be to take an action, such as setting the state of an LED or LEDs, saving the millis() value at that time then going round loop() until the required period in that state has elapsed. When it does, set the outputs to the next values, save the time and keep going like this.

The advantage is that you can read inputs at each iteration of loop() and react to them straight away rather than waiting for a pattern to complete or reading the inputs at multiple places in the code.

UKHeliBob:
Probably not necessary

You have not posted your code but if written properly the loop() function will run every couple of milliseconds at the most so you can read the pot very frequently and use sensorValue wherever you need it.

Your program presumably has blocking code in it such as for loops, while loops and delay(). Eliminate them and your problem will be solved.

See Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE for ideas how to do it.

Thanks UKHeliBob,
I read your examples, most enlightening!

Considering your 25k of source code, an interrupt driven approach might actually be simpler for you because you would not have to modify any of it. I am loathe to recommend it because you will stumble into the same trap if you design another program. But perhaps, it is not your code?

aarg:
Considering your 25k of source code, an interrupt driven approach might actually be simpler for you because you would not have to modify any of it. I am loathe to recommend it because you will stumble into the same trap if you design another program. But perhaps, it is not your code?

Noooo.... It is not my code! I'm a REAL noobie to this whole Arduino world! Only discovered it a few months ago (building a 3D printer) I used to program a lot of C in Linux but now days it's mostly RAPID. (ABB robot code)

I haven't really even looked into the interrupt thing yet. As you say, probably an easier approach as the changes would be less, but the "millis" approach seems way superior! Besides, I'm not looking to perfect the code, just learn from it, good or bad!

I am not sure that using an interrupt driven solution is going to be easy.

Imagine that the program is in the midst of running a sequence that may take minutes according to the OP, and the button is pressed causing an interrupt. The ISR runs and what does it do, set a flag maybe ? Whatever it does, when it is finished the program will resume at the place where it was interrupted so the flag will need to be checked at multiple places in the code and action taken.

UKHeliBob:
I am not sure that using an interrupt driven solution is going to be easy.

Imagine that the program is in the midst of running a sequence that may take minutes according to the OP, and the button is pressed causing an interrupt. The ISR runs and what does it do, set a flag maybe ? Whatever it does, when it is finished the program will resume at the place where it was interrupted so the flag will need to be checked at multiple places in the code and action taken.

The speed would change with the pot position instantaneously if sensorValue is updated by an interrupt, which seems like a good thing.

     delay(sensorValue);

controls the display speed

Um... Why not use:

delay(analogRead(sensorPin));

in place of:

sensorValue = analogRead(sensorPin);  delay(sensorValue);

You could also create a macro at the top:

#define DELAY delay(analogRead(sensorPin))

Then just put DELAY; where you want the variable delay.

Thanks johnwasser! :smiley:

Since forking the process off is not possible and t he mills approach would require a complete rewrite (although for future projects it's a good way to go) this kind of 1-liner is exactly the kind thig that I am looking for!

Cheers!!