0

I am using Arduino in an IOT application where I have to read impulses coming from a sensor and send a mean value of these impulses without missing any impulse while sending the value so is it possible to achieve such operation knowing that Arduino is a single core chip.

I read about Protothreading libraries but it may miss an impulse during the check phase so I want to know if there is another solution

8
  • One word: Interrupts. Google them.
    – Majenko
    Jul 9 '18 at 10:22
  • Post some more details of what you are trying to achieve. You want to count pulses? Interrupts as Majenko said.
    – MichaelT
    Jul 9 '18 at 10:25
  • yes i need to count pulses so i dont want that at the moment when i send a value, i miss a pulse
    – bouhmid
    Jul 9 '18 at 10:31
  • I have googled for polthread and pollthread, and can't find anything. Can't you provide a link. Regardless, count each impulse in a ISR (one statement should do it) and in the loop() you can calculate and output the mean using 'millis()` Jul 9 '18 at 10:36
  • sorry ,its protothreading here is a link hackster.io/reanimationxp/…
    – bouhmid
    Jul 9 '18 at 10:38
0

Although the Arduino only has one CPU core and can only execute one program instruction at a time, it's not limited to only doing one thing at a time.

An MCU is a complex device with lots and lots of peripheral devices built into it. The CPU is only one small block of the overall device.

Much of a program is merely instructions telling the peripherals how to perform.

For instance, when sending data through Serial the CPU doesn't say "Send this bit. Now wait. Now send this bit. Now wait again" - instead it just says "Here's this byte to send. Now go and send it and tell me when you're done". The UART peripheral then sends the byte by itself with no further input from the CPU leaving the CPU free to do other things.

Then there's the Timer peripherals. The CPU sets them up to count from a clock source, and do different things depending on different events, like a specific number is reached in the counting, etc. The CPU has no need to go "Count up one. Count up one. Count up one." - it just goes "Count up from 0 using this clock source and tell me when you reach 100" (for example).

Similarly, there are "External Interrupts". The CPU doesn't need to sit watching an IO pin all the time, going "Have you changed yet? Have you changed yet? Have you changed yet?" - it just goes "Tell me when you have changed" and the CPU goes off to do other things.

Of course, all these things have caveats. The biggest is that if the CPU is doing something very timing critical, such as "bit banging" serial data manually through a GPIO pin (for example with SoftwareSerial) it can be set to ignore all these interrupt signals from the peripherals. That means, if you're using an "External Interrupt" to count pulses, and you have to use SoftwareSerial to communicate, it's possible that SoftwareSerial's sending or receiving routines could cause the detection of a pulse to be either delayed (not really a problem) or to be missed completely.

So you don't want to use SoftwareSerial if it can be avoided if you want to use External Interrupts for this kind of operation.

The other option is to use a timer. I mentioned that they just count up from 0 (or they can count down, too) using a configurable clock source. That counting happens completely independently of the CPU, and carries on regardless of whether interrupts are enabled or disabled. And the great new is that most timers can be configured (depending on which Arduino you use) to use an external signal as the clock source for the counting.

That means you can configure a timer to count your pulses for you regardless of what the CPU is doing. All you have to do is every so often (how often depends on how frequently your pulses arrive - the timer has a limit on how many it can count before it overflows) ask the timer for what it has counted up to and reset its count to 0. That could be done as part of your "sending" routine. Get the count, reset it to 0, and send the results.

4
  • what if the frequency that i am counting is variable? can the timer solution still work
    – bouhmid
    Jul 9 '18 at 11:20
  • Yes. It just cares about edges. As long as the number of pulses you need to count is less than the maximum the timer can count (or you "expand" it using the overflow interrupt) within the period at which you read-and-reset the count it doesn't care what the frequency is (as long as it's below 1/2 the system clock frequency).
    – Majenko
    Jul 9 '18 at 11:21
  • i get ur solution however if i use the timer as a counter how would i know the time during witch i counted my pulses to get a mean value ?
    – bouhmid
    Jul 9 '18 at 11:28
  • There is more than one timer. Timer0 drives millis().
    – Majenko
    Jul 9 '18 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.