Skip to content
This repository has been archived by the owner on Jan 29, 2023. It is now read-only.

Issue w/ AnalogRead in Interrupt #5

Closed
daanstevenson opened this issue Aug 30, 2021 · 1 comment
Closed

Issue w/ AnalogRead in Interrupt #5

daanstevenson opened this issue Aug 30, 2021 · 1 comment
Labels
Support Library support

Comments

@daanstevenson
Copy link

daanstevenson commented Aug 30, 2021

Hi Khoi,
Thanks for writing and sharing this timer interrupt library.
I am trying to implement consistently spaced sampling on a Nano33BLE, but the board seems to crash whenever I have a call to analogRead within the ISR.

Arduino IDE version: 1.8.13
Arduino mbed Nano Core Version 2.4.1
OS: Windows 10

Minimal code is below. I have also tried with an Adafruit nrf52 board and your other version of the library. This seems to work, but only if interrupts are halted before the analogRead call and enabled afterwards.

Working on native Nordic SDK firmware, but it would be great to accelerate prototyping with your library!

// test of timer ADC functionality

#include "NRF52_MBED_TimerInterrupt.h"

#define MOTOR_PIN P0_27 // 9u, D9
#define OPTO_PIN P0_21 // 8u, D8
#define FIELD_MILL_PIN P0_5 // 15u, A1

#define SAMPLE_INTERVAL 500
#define BLE_INTERVAL 10000

NRF52_MBED_Timer sample_timer(NRF_TIMER_4);
NRF52_MBED_Timer ble_timer(NRF_TIMER_3);

volatile int idx;
volatile unsigned long times[20] = {};
volatile int readings[20] = {};
volatile int fm_output = 0;

unsigned long t_now; // start time for current loop
unsigned long t_last_sample = 0;
unsigned long sample_delay = 5000;
unsigned long t_last_print = 0;
unsigned long print_delay = 500E3;

void setup() {
// put your setup code here, to run once:

Serial.begin(57600);

analogReadResolution(12);

sample_timer.attachInterruptInterval(SAMPLE_INTERVAL, SampleTimerFunc);
ble_timer.attachInterruptInterval(BLE_INTERVAL, BleTimerFunc);

}

void loop() {
// put your main code here, to run repeatedly:

t_now = micros();
// if (t_now - t_last_sample > sample_delay)
// {
// t_last_sample = t_now;
// times[idx] = micros();
// readings[idx] = analogRead(FIELD_MILL_PIN);
// idx++;
// if (idx >= 20)
// {
// idx = 0;
// }
// }

// Print debug data
if (t_now - t_last_print > print_delay)
{
t_last_print = t_now;
Serial.println(fm_output);
for (int i = 0; i < 20; i++)
{
Serial.print(times[i]);
Serial.print("\t");
}
Serial.println();
for (int i = 0; i < 20; i++)
{
Serial.print(readings[i]);
Serial.print("\t");
}
Serial.println();
}
}

void SampleTimerFunc()
{
times[idx] = micros();
// noInterrupts();
readings[idx] = analogRead(FIELD_MILL_PIN);
// interrupts();
// readings[idx] = 200;

idx++;
if (idx >= 20)
{
idx = 0;
}
}

void BleTimerFunc()
{
int total = 0;
for (int i = 0; i < 20; i++)
{
total += readings[i];
}
fm_output = (int)(76.0 * (double)total / 20.0);
}

@khoih-prog
Copy link
Owner

khoih-prog commented Aug 30, 2021

As a rule, you can't do something too long in ISR, especially using the messy analogRead().

The correct way to do is set a flag inside ISR, then call analogRead() outside ISR using a loop depending on millis().

Also have a look at analogRead #2

Thanks for your interest in the library.

Good Luck,

@khoih-prog khoih-prog added the Support Library support label Aug 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Support Library support
Projects
None yet
Development

No branches or pull requests

2 participants