hello i'm making machine with encoder .I have a problem probably with AttachInterupt() because if i run this machine on this cycle (+10000steps-10000steps) it's run perfectly and if i run machine on this cycle (+10000steps ,60s of break, - 10000steps ) for +10000 steps its work perfectly and if break is done there is some problem like sleeping(?) or reaction delay(?) thats machine counts from zero i don't know what is it ? this is my code:
// Autor: Mariusz i Stanisław Kaczmarek
#include <SD.h>
int SD_WRITE = 0;
File myFile;
#define PIN_SPI_CS 4
#include <ArrayList.h>
int save_done =0;
long cdk = 0;
volatile long encoderPosition = 0;
int continue321 = 1;
int encoderPinA = 2;
int encoderPinB = 3;
int lastEncoded = 0;
int przycisk = 0;
int continue123 = 0;
int przerwa = 0;
int opi = 0;
int myList[70] = {};
int myList2[70] = {};
long przerwa2 = 0;
#include <SPI.h>
#include <List.hpp>
#include <stdlib.h>
//List<int> myList;
//List<int> myList2;
Sd2Card card;
SdVolume volume;
SdFile root;
// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 4;
void setup() {
Serial.begin(2000000);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
if (!SD.begin(4)) {
Serial.println("initialization failed!");
digitalWrite(5 , HIGH);
while (1);
}
attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoderPinB), updateEncoder, CHANGE);
pinMode(encoderPinA, INPUT_PULLUP);
pinMode(encoderPinB, INPUT_PULLUP);
pinMode(A1 , INPUT);
pinMode(9, INPUT_PULLUP);
pinMode(5 , OUTPUT);
delay(1000);
digitalWrite(5 , LOW);
}
void loop() {
if (SD_WRITE == 1 && save_done ==0 ){
myFile = SD.open("test.txt", FILE_WRITE);
if (myFile) {
myFile.println("NEXT_TEST:");
detachInterrupt(digitalPinToInterrupt(2));
detachInterrupt(digitalPinToInterrupt(3));
Serial.println("Zapisywanie do karty sd...");
for (int i = 0; i <= 70; i++) {
Serial.println(myList[i]);
myFile.println(myList2[i]);
Serial.println(myList2[i]);
myFile.println(myList[i]);
}
digitalWrite(5 , HIGH);
myFile.close();
}
else{
Serial.println("error opening test.txt");
}
save_done = 1;
}
if (digitalRead(9) == LOW && przycisk == 0){
Serial.println("START");
encoderPosition = 0;
przycisk = 1;
Serial.println(encoderPosition);
Serial.println(continue123);
Serial.println(przycisk);
}
if (przycisk == 1 && (millis() - przerwa )>= 1000){
myList[cdk] = (analogRead(A1)/20.46);
myList2[cdk] = (encoderPosition);
przerwa = millis();
cdk++;
}
}
void updateEncoder() {
int MSB = digitalRead(encoderPinA); // Most significant bit
int LSB = digitalRead(encoderPinB); // Least significant bit
int encoded = (MSB << 1) | LSB; // Converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; // Adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderPosition --;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderPosition ++;
lastEncoded = encoded; // Store this value for next time
Serial.println(encoderPosition);
//Serial.println(encoderPosition);
if (encoderPosition >= 9000 && continue123 == 0 && przycisk == 1 ){
encoderPosition = 9000;
Serial.println("ENCODER_POSTION9000");
continue123 = 1;
digitalWrite(5 , HIGH);
}
if (encoderPosition <= 0 && continue123 == 1 ){
encoderPosition = 0;
Serial.println("ENCODER_POSTION0");
digitalWrite(5 , LOW);
przycisk = 0;
continue123 =0;
SD_WRITE = 1;
}
}
no I don't see the message from the encoder for a while, as if the Arduino had a delayed reaction and the Enkoderpositoin starts counting from zero, not from 9000
Detaching then reattaching the interrupt in loop() is just wrong. If you must suspend interrupt processing, use a (volatile) flag in the ISR to simply return. Update that flag when you want to start processing again.
But, why do you think you need to suspend interrupt processing in the first place?
I'm trying something like a tonometer or an indentation device - this thing is supposed to rotate 9000 degrees in the extended motor, wait 60 seconds and then withdraw also by 9000 degrees and at the same time save the results on the SD card from the force sensor and encoder and display messages in Polish on the display. To make this project I used 2 Arduino Nanos - if it's a question of performance, I can replace the Arduino Nano with an Arduino Portenta H7
The #1 code has a lot of printing in the interrupt (move those into loop) and uses lots of non-volatile ints to communicate one-bit flags with loop (make those volatile bytes).
I think it is intended as a one-shot file write and you need to re-cycle the power to do a new write cycle.