As I know, noInterrupts() and interrupts() are required for volatile variable is bigger than a byte but do I also call noInterrupts() and interrupts() for volatile uint8_t array ?
Example;
#include "LoraFunctions.h"
/* Pins of External Interrupts */
const uint8_t pulsePins[] = {A1, A2, 0, 1, 4, 5, 6, 7};
const uint16_t minPulseTimeWidth = 700;
volatile uint8_t pulseArray[] = {0, 0, 0, 0, 0, 0, 0, 0};
volatile unsigned long lastHighTrigTime[] = {0, 0, 0, 0, 0, 0, 0, 0};
// encrepted uint8_t values of pulseArray is stored
uint8_t payload[8];
void interruptPin0() {
uint8_t arrayValueOfPin = 0;
if (digitalRead(pulsePins[arrayValueOfPin]) == HIGH) {
lastHighTrigTime[arrayValueOfPin] = millis();
} else if (millis() - lastHighTrigTime[arrayValueOfPin] > minPulseTimeWidth) {
pulseArray[arrayValueOfPin]++;
}
}
.
.
.
void interruptPin7() {
uint8_t arrayValueOfPin = 7;
if (digitalRead(pulsePins[arrayValueOfPin]) == HIGH) {
lastHighTrigTime[arrayValueOfPin] = millis();
} else if (millis() - lastHighTrigTime[arrayValueOfPin] > minPulseTimeWidth) {
pulseArray[arrayValueOfPin] = 1;
}
}
void setup() {
debugSerial.begin(115200);
for (uint8_t i = 0; i < ARRAY_SIZE(pulseArray); i++) {
pinMode(pulsePins[i], INPUT);
}
attachInterrupt(digitalPinToInterrupt(pulsePins[0]), interruptPin0, CHANGE);
.
.
.
attachInterrupt(digitalPinToInterrupt(pulsePins[7]), interruptPin7, CHANGE);
delay(500);
}
void loop() {
delay(300000);
sendMessageToGateway();
}
void sendMessageToGateway() {
buildPacket();
modem.beginPacket();
modem.write(payload, 8);
if (modem.endPacket(true) > 0) {
printlnToScreen("Message sent correctly!");
resetArrays();
} else {
printlnToScreen("Error sending message :(");
}
}
// Reset all elements in the array to 0
void resetArrays() {
for (uint8_t i = 0; i < ARRAY_SIZE(pulseArray); i++) {
pulseArray[i] = 0;
}
}
// Encode array values as uint8_t
void buildPacket() {
for (uint8_t i = 0; i < ARRAY_SIZE(pulseArray); i++) {
payload[i] = pulseArray[i];
}
}
The reason you call noInterrupts() is when working with several registers that represent data as a whole, for example a 4 registers that represent 1 32-bit variable. So, let's take an example: you have a volatile char array named hw[] that is a c-style string that flips from "Hello" to "World" each time an interrupt fires. You call Serial.print(hw); If the interrupt fires while in the print loop, you might send "Herld" instead. Now, lets say your volatile uint8_t pulseArray[] isn't contiguous data, taken as a whole. Given the snippet above, we don't really know, so you have to answer that for yourself. Is there a point in your actual code where you would iterating over the array and might get halfway, while the other half would contain updated data... Setting the array to zero would not require noInterrupts() unless it was important that they all be zero at the same time.
As @Robin2 noted, you did not provide sufficient context. The accesses to the individual uint8_t elements of the array will be atomic. So, the individual values will not be corrupted. But, is it important to you that none of the elements get updated while the entire array is being accessed in loop()? No way to tell from what you've shown.
I updated code to give more precise information. I am still confused, on loop I am trying to access each element of array and each element size is 8 bit, I think there is no problem here. But, what happens when one of element is modified and external interrupts occurs ?
I'll assume that you are not doing anything goofy... if not, you don't need to disable interrupts to read 8 bit atomic values in an array. You're probably worried because it's multibyte. But each array member access is atomic.
If you are also passing any array index or any other values that are multi-byte, those do have to be protected. I think the reason red flags have gone up here is because we don't know if the array is "synchronized", i.e. whether some but not all values have been updated by the ISR. If there is a requirement that all the values must be taken as a unit, you need more than just an array anyway, you need to pass some flag or counter to indicate that the array is "ready to read", i.e. complete, and the ISR has to set that flag when it has determined that the array is "ready to pass". Merely disabling interrupts is not enough in that circumstance. That is because the main program can't determine whether an array update by the ISR is in mid progress. Again, disabling interrupts won't help you with that.
As for your code, I'm sorry, I don't read code that isn't commented. Not more than 10 lines or so.