Arduino NANO verliest programma
9 berichten
• Pagina 1 van 1
Arduino NANO verliest programma
Hallo allemaal.
Ik heb wel eens de indruk dat wanneer IK iets vraag, dat het dan pas echt moeilijk wordt... Dus daar komt ie:
Met een Arduino NANO heb ik wat gemaakt dat een 16x2 lcd (HD44780) aanstuurt, een kanaal van een radio-bestuurd vliegtuigje inleest, en ook wat servo's aanstuurt. Dat programma werkt op zich prima. Weerstanden aan de ingangen gemaakt om deze hoog of laag te houden als er geen signaal aanwezig is, en het werkt top. Dat display is vooral voor mij interresant, want dan weet ik precies wanneer er wat gebeurd. De gebruiker kan op het display de waarden aflezen die hij de servo's wil geven als hij e.e.a wil instellen. Maar instellen doe je niet vaak, daarom kwam al snel de vraag of het display weg kan blijven. Nou ja, dispay stekker er uit laten (SCL,SDA, VCC en GND), en alles blijft gewoon werken. Ik heb het 100 keer geprobeerd, en meestal gaat dat goed. Het zit 'm dus in het woord "meestal".
Het LIJKT dat wanneer er geen display gemonteerd wordt, de Arduino soms zijn programma verliest. Wat ik ook doe, alleen na herprogrammmeren met het zelfde programma, dan werkt alles weer. Nu weet ik het even niet meer. Als ik er helemaal niet uitkom, dan monteer ik een Jumper. Jumper gesloten = display aanwezig, jumper onderbroken = geen display. En die Jumper wordt dan natuurlijk ingelezen.
Mijn vraag is: Wat zou ik moeten doen om de Arduino zijn programma te laten verliezen? Rare vraag he!
Ik heb sterk de indruk dat het met het LCD te maken heeft. Wie kan me helpen?
Ik heb wel eens de indruk dat wanneer IK iets vraag, dat het dan pas echt moeilijk wordt... Dus daar komt ie:
Met een Arduino NANO heb ik wat gemaakt dat een 16x2 lcd (HD44780) aanstuurt, een kanaal van een radio-bestuurd vliegtuigje inleest, en ook wat servo's aanstuurt. Dat programma werkt op zich prima. Weerstanden aan de ingangen gemaakt om deze hoog of laag te houden als er geen signaal aanwezig is, en het werkt top. Dat display is vooral voor mij interresant, want dan weet ik precies wanneer er wat gebeurd. De gebruiker kan op het display de waarden aflezen die hij de servo's wil geven als hij e.e.a wil instellen. Maar instellen doe je niet vaak, daarom kwam al snel de vraag of het display weg kan blijven. Nou ja, dispay stekker er uit laten (SCL,SDA, VCC en GND), en alles blijft gewoon werken. Ik heb het 100 keer geprobeerd, en meestal gaat dat goed. Het zit 'm dus in het woord "meestal".
Het LIJKT dat wanneer er geen display gemonteerd wordt, de Arduino soms zijn programma verliest. Wat ik ook doe, alleen na herprogrammmeren met het zelfde programma, dan werkt alles weer. Nu weet ik het even niet meer. Als ik er helemaal niet uitkom, dan monteer ik een Jumper. Jumper gesloten = display aanwezig, jumper onderbroken = geen display. En die Jumper wordt dan natuurlijk ingelezen.
Mijn vraag is: Wat zou ik moeten doen om de Arduino zijn programma te laten verliezen? Rare vraag he!
Ik heb sterk de indruk dat het met het LCD te maken heeft. Wie kan me helpen?
- Code: Alles selecteren
/***************************************************************
Program name: RC_Plane_doors
Board: Arduimo Nano / Arduino Mini Pro
Processor: ?
This program sequence the plane retract doors, and retracts
!!! Add a 10K resistor from the IRQ 0 and IRQ 1 input to the
ground or 5V. So that input is defined.
Licence: free to / modify / spread
Progranm description: //description deleted
PC13 LED: ON or OFF, the Arduino is busy.
Blinking: the Arduino is in idle, and wait for a command.
***************************************************************/
#define DEBUG //Uncommment if DEBUG is not needed
//#define DefaultValueToEeprom
//include files
#include <Servo.h> //NNeeded for the servo's
#include <LiquidCrystal_I2C.h> //Needed for LCD
#include <EEPROM.h> //Needed for EEPROM
//Create a servo object
Servo FrontDoorServo; // create servo object to control a servo
Servo LeftDoorServo; // create servo object to control a servo
Servo RightDoorServo; // create servo object to control a servo
Servo WheelServo; // create servo object to control a servo
//Setup 16 x 2 Serial LCD connections (Standaard SDA en SCL worden gebruikt)
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display
//Define buttons
int ButtonPin = A0;
float ButtonValue; // variable for reading witch button i pressed
int ButtonState;
//Define variabeles
int IRQ_0_Nr = 0; // IRQ-0
int IRQ_1_Nr = 1; // IRQ-1
int IRQ_0_pin = 2; // IRQ-0
int IRQ_1_pin = 3; // IRQ-1
unsigned int FrontDoorServo_Min;
unsigned int FrontDoorServo_Max;
unsigned int LeftDoorServo_Min;
unsigned int LeftDoorServo_Max;
unsigned int RightDoorServo_Min;
unsigned int RightDoorServo_Max;
unsigned int WheelServo_Min;
unsigned int WheelServo_Max;
bool SwitchNewSignal = false;
unsigned long SwitchStartPeriod = 0;
unsigned long SwitchEndPeriod = 0;
unsigned long SwitchPulseLength;
bool LG_Down = true;
int KeyDelay = 100;
void setup() {
//Define Serial port
Call_InitSerial();
//Write default values to Eprom in case something went wrong
#ifdef DefaultValueToEeprom
unsigned int FrontDoorServo_Min = 1100;
EEPROM.put(0, FrontDoorServo_Min);
unsigned int FrontDoorServo_Max = 1900;
EEPROM.put(2, FrontDoorServo_Max);
unsigned int LeftDoorServo_Min = 1100;
EEPROM.put(4, LeftDoorServo_Min);
unsigned int LeftDoorServo_Max = 1900;
EEPROM.put(6, LeftDoorServo_Max);
unsigned int RightDoorServo_Min = 1100;
EEPROM.put(8, RightDoorServo_Min);
unsigned int RightDoorServo_Max = 1900;
EEPROM.put(10, RightDoorServo_Max );
unsigned int WheelServo_Min = 1100;
EEPROM.put(12, WheelServo_Min);
unsigned int WheelServo_Max = 1900;
EEPROM.put(14, WheelServo_Max);
#endif
#ifdef DEBUG
Call_Show_EpromTable();
#endif
//LCD initialise
lcd.init(); // Initialize the lcd SDA = A4 SCL = A5
lcd.clear(); // LCD clear
lcd.backlight(); // Backlight on
//lcd.noBacklight(); // Backlicht off
//Check if Select button is pressed if so
//set Eeprom default value''s
ButtonState = Call_Read_ButtonState();
if (ButtonState == 3) { //Select
#ifdef DEBUG
Serial.println();
Serial.println("SelectKey is pressed now");
#endif
Call_Set_EepromToDefaultValues();
} //if
//If no select buttin is pressed then continue
lcd.setCursor(0, 0); // X, Y
lcd.print(" Sequencer V-1 ");
lcd.setCursor(0, 1); // X, Y
lcd.print("by Leon Boulart");
delay(1000);
//Startup delay
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task:");
lcd.setCursor(0, 1); // X, Y
lcd.print("Startup delay ");
for (int i=3;i>=0;i+=-1) {
lcd.setCursor(15, 1); // X, Y
lcd.print(i);
delay(1000);
}
//Read Eprom to variables
Call_Read_Eprom_Values();
//Define pinModes
pinMode(LED_BUILTIN, OUTPUT);
pinMode(ButtonPin, INPUT);
//Define the servo start positon
FrontDoorServo.write(FrontDoorServo_Max); //Door = open
LeftDoorServo.write(LeftDoorServo_Max); //Door = open
RightDoorServo.write(RightDoorServo_Max); //Door = open
WheelServo.write(WheelServo_Min); //Wheel = down
//Define Servo
FrontDoorServo.attach(PD4); // attaches the servo on pin D4 to the servo object
LeftDoorServo.attach(PD5); // attaches the servo on pin D5 to the servo object
RightDoorServo.attach(PD6); // attaches the servo on pin D6 to the servo object
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Force doors down");
//Delay time
for (int i=3; i>=0; i+=-1) {
lcd.setCursor(15, 0); // X, Y
lcd.print(i);
delay(1000);
};
WheelServo.attach(PD7); // attaches the servo on pin D6 to the servo object
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Force retr. down");
//Delay time
for (int i=3; i>=0; i+=-1) {
lcd.setCursor(15, 0); // X, Y
lcd.print(i);
delay(1000);
};
//Define IRQ
digitalPinToInterrupt(IRQ_0_pin);
attachInterrupt(digitalPinToInterrupt(IRQ_0_pin), Call_IRQ_0, CHANGE);
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Wait for command");
} //setup
void loop() {
//flashing LED_BUILTIN
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
delay(100);
/*
//use this part for a reverse gear switch
if(NewSignal) {
if (PulseLength >= 1700 && LG_Down == false) {
Call_LandingGear_Down();
}
else {
if (PulseLength < 1700 && LG_Down == true) {
Call_LandingGear_Up();
}
}
*/
//Use this part nor a normal gear switch
if(SwitchNewSignal) {
if (SwitchPulseLength <= 1700 && LG_Down == false) { //Pulselength 200 uS less than max pulse length
Call_LandingGear_Down();
}
else {
if (SwitchPulseLength > 1700 && LG_Down == true) {
Call_LandingGear_Up();
}
}
SwitchNewSignal = false;
}
if (SwitchNewSignal == false) {
//lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Wait for command");
}
//Check if Select button is pressed
ButtonState = Call_Read_ButtonState();
if (ButtonState == 3) {
Call_Adjust_Mode();
} //if
#ifdef DEBUG
Serial.print(" SwitchPulseLength = ");Serial.print(SwitchPulseLength);Serial.print(" ");
#endif
} //loop
void Call_InitSerial() {
#ifdef DEBUG
Serial.begin(9600);
Serial.println();
Serial.print("file: ");
Serial.print(__FILE__); //Warning: 2x underscore
Serial.println();
Serial.print("Have been started...");
Serial.println();
Serial.print("..End of Call_InitSerial() = line: \t");
Serial.println(__LINE__);
#endif
} //CALL_InitSerial()
void Call_IRQ_0() {
//This interrupt is called even when the signal go high or go low.
if(digitalRead(IRQ_0_pin) == HIGH) { //rising edge
SwitchStartPeriod = micros();
}
else { //falling edge
if(SwitchStartPeriod && (SwitchNewSignal == false)) {
SwitchEndPeriod = micros();
SwitchPulseLength = SwitchEndPeriod - SwitchStartPeriod;
SwitchStartPeriod = 0;
SwitchNewSignal = true;
}
}
} //Call_IRQ_0
void Call_LandingGear_Down() {
//Turn off the interrupt
detachInterrupt(digitalPinToInterrupt(IRQ_0_pin));
//Door Open
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Opening doors");
//Opening front door
for (int i = FrontDoorServo_Min; i <= FrontDoorServo_Max; i += 1) {
FrontDoorServo.write(i);
delay(1);
}
//Opening left door
for (int i = LeftDoorServo_Min; i <= LeftDoorServo_Max; i += 1) {
LeftDoorServo.write(i);
delay(1);
}
//Opening right door
for (int i = RightDoorServo_Min; i <= RightDoorServo_Max; i += 1) {
RightDoorServo.write(i);
delay(1);
}
delay(4000); //delay beween door open, and gear down
/*
//Wheel down normal servo
for (int i = WheelServo_Min; i <= WheelServo_Max; i += 1) {
WheelServo.write(i);
delay(1);
}
delay(4000); //delay beween door open, and gear down
*/
//Wheel down with reversed servo
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Wheels move down");
for (int i = WheelServo_Max; i >= WheelServo_Min; i += -1) {
WheelServo.write(i);
delay(1);
}
LG_Down = true;
//Turn on the interrupt
attachInterrupt(digitalPinToInterrupt(IRQ_0_pin), Call_IRQ_0, CHANGE);
} //LandingGear_Down
void Call_LandingGear_Up() {
//Turn off the interrupt
detachInterrupt(digitalPinToInterrupt(IRQ_0_pin));
/*
//Wheel_Up normal servo
for (int i = WheelServo_Max; i >= WheelServo_Min; i += -1) {
WheelServo.write(i);
delay(1);
}
*/
//Wheel_Up with reversed servo
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Wheels move up");
for (int i = WheelServo_Min; i <= WheelServo_Max; i += 1) {
WheelServo.write(i);
delay(1);
}
delay(4000); //delay beween wheel up, and door closed
//Door Close
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Closing doors");
//Closing front door
for (int i = FrontDoorServo_Max; i >= FrontDoorServo_Min; i += -1) {
FrontDoorServo.write(i);
delay(1);
}
//Closing left door
for (int i = LeftDoorServo_Max; i >= LeftDoorServo_Min; i += -1) {
LeftDoorServo.write(i);
delay(1);
}
//Closing right door
for (int i = RightDoorServo_Max; i >= RightDoorServo_Min; i += -1) {
RightDoorServo.write(i);
delay(1);
}
LG_Down = false;
//Turn on the interrupt
attachInterrupt(digitalPinToInterrupt(IRQ_0_pin), Call_IRQ_0, CHANGE);
} //LandingGear_Up
void Call_Show_EpromTable() {
#ifdef DEBUG
unsigned int Value;
Serial.println();
Serial.println("Eprom table:");
for (int i=0; i<=20; i+=2) {
Value = EEPROM.get(i, Value);
Serial.print("Adres ");Serial.print(i);Serial.print(" = ");Serial.print(Value);
Serial.println();
} //for
#endif
} //Call_Show_EpromTable
void Call_Read_Eprom_Values() {
//unsigned int FrontDoorServo_Min;
EEPROM.get(0, FrontDoorServo_Min);
//unsigned int FrontDoorServo_Max;
EEPROM.get(2, FrontDoorServo_Max);
//unsigned int LeftDoorServo_Min;
EEPROM.get(4, LeftDoorServo_Min);
//unsigned int LeftDoorServo_Max;
EEPROM.get(6, LeftDoorServo_Max);
//unsigned int RightDoorServo_Min;
EEPROM.get(8, RightDoorServo_Min);
//unsigned int RightDoorServo_Max;
EEPROM.get(10, RightDoorServo_Max );
//unsigned int WheelServo_Min;
EEPROM.get(12, WheelServo_Min);
//unsigned int WheelServo_Max;
EEPROM.get(14, WheelServo_Max);
} //Call_Read_Eprom_Values
int Call_Read_ButtonState() {
//Read Buttons
ButtonValue = analogRead(ButtonPin);
//Select Key
if (ButtonValue >= 345) {
ButtonState = 3; //Button = Select
} //if
//Select Key
if (ButtonValue > 200 && ButtonValue < 345) {
ButtonState = 2; //Button = +
} //if
//Select Key
if (ButtonValue > 50 && ButtonValue <= 200) {
ButtonState = 1; //Button = -
} //if
//Select Key
if (ButtonValue <= 50 ) { //Button = -
ButtonState = 0; //No Button is pressed.
} //if
return ButtonState;
} //Call_Read_ButtonState
void Call_Adjust_Mode() {
//Turn off the interrupt
detachInterrupt(digitalPinToInterrupt(IRQ_0_pin));
//Update display
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task:Adjust mode");
lcd.setCursor(0, 1); // X, Y
lcd.print("One moment...");
delay(1000);
//Adjust with landingGear Down
if (LG_Down) {
//Adjust FrontDoorServo_Max
Call_Adjust_FrontDoorServo_Max();
Call_Adjust_LeftDoorServo_Max();
Call_Adjust_RightDoorServo_Max();
Call_Adjust_WheelServo_Min();
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Retracts move up");
//Delay time
for (int i=3; i>=0; i+=-1) {
lcd.setCursor(15, 0); // X, Y
lcd.print(i);
delay(1000);
};
Call_LandingGear_Up();
Call_Adjust_FrontDoorServo_Min();
Call_Adjust_LeftDoorServo_Min();
Call_Adjust_RightDoorServo_Min();
Call_Adjust_WheelServo_Max();
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Retracts move dn");
//Delay time
for (int i=3; i>=0; i+=-1) {
lcd.setCursor(15, 0); // X, Y
lcd.print(i);
delay(1000);
};
Call_LandingGear_Down();
} //if
else {
//Adjust FrontDoorServo_Min
} //else
//Turn on the interrupt
attachInterrupt(digitalPinToInterrupt(IRQ_0_pin), Call_IRQ_0, CHANGE);
} //Call_Adjust_Mode
void Call_Adjust_FrontDoorServo_Max() {
//Adjust Frontdoor servo Max
FrontDoorServo_Max= EEPROM.get(2, FrontDoorServo_Max); //Adres 2 + 3 = FrontDoorServo_Max
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("F.door Max= ");lcd.print(FrontDoorServo_Max);
lcd.setCursor(0, 1); // X, Y
lcd.print("Select or - or +");
ButtonState = -1; // In case the Select switch is still pressed
//Set FrontDoorServo_Max
while (ButtonState !=3) { // As long as not Select is pressed
ButtonState = Call_Read_ButtonState();
switch (ButtonState) {
case 1: // -
FrontDoorServo_Max++;
break;
case 2: // +
FrontDoorServo_Max--;
break;
};
FrontDoorServo.write(FrontDoorServo_Max);
lcd.setCursor(12, 0); // X, Y
if (FrontDoorServo_Max < 1000) { lcd.print("0"); };
lcd.print(FrontDoorServo_Max);
delay(KeyDelay);
};
EEPROM.put(2, FrontDoorServo_Max); // Adres 2 and 3 = FrontDoorServo_Max
} //Call_Adjust_FrontDoorServo_Max
void Call_Adjust_LeftDoorServo_Max() {
//Adjust Leftdoor servo Max
LeftDoorServo_Max= EEPROM.get(6, LeftDoorServo_Max); //Adres 6 + 7 = LeftDoorServo_Max
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("L.door Max= ");lcd.print(LeftDoorServo_Max);
lcd.setCursor(0, 1); // X, Y
lcd.print("Select or - or +");
ButtonState = -1; // In case the Select switch is still pressed
//Set LeftDoorServo_Max
while (ButtonState !=3) { // As long as not Select is pressed
ButtonState = Call_Read_ButtonState();
switch (ButtonState) {
case 1: // -
LeftDoorServo_Max++;
break;
case 2: // +
LeftDoorServo_Max--;
break;
};
LeftDoorServo.write(LeftDoorServo_Max);
lcd.setCursor(12, 0); // X, Y
if (LeftDoorServo_Max < 1000) { lcd.print("0"); };
lcd.print(LeftDoorServo_Max);
delay(KeyDelay);
};
EEPROM.put(6, LeftDoorServo_Max); // Adres 6 and 7 = LeftDoorServo_Max
} //Call_Adjust_LeftDoorServo_Max
void Call_Adjust_RightDoorServo_Max() {
//Adjust Rightdoor servo Max
RightDoorServo_Max= EEPROM.get(10, RightDoorServo_Max); //Adres 10 + 11 = RightDoorServo_Max
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("R.door Max= ");lcd.print(RightDoorServo_Max);
lcd.setCursor(0, 1); // X, Y
lcd.print("Select or - or +");
ButtonState = -1; // In case the Select switch is still pressed
//Set RightDoorServo_Max
while (ButtonState !=3) { // As long as not Select is pressed
ButtonState = Call_Read_ButtonState();
switch (ButtonState) {
case 1: // -
RightDoorServo_Max++;
break;
case 2: // +
RightDoorServo_Max--;
break;
};
RightDoorServo.write(RightDoorServo_Max);
lcd.setCursor(12, 0); // X, Y
if (RightDoorServo_Max < 1000) { lcd.print("0"); };
lcd.print(RightDoorServo_Max);
delay(KeyDelay);
};
EEPROM.put(10, RightDoorServo_Max); // Adres 10 and 12 = RightDoorServo_Max
} //Call_Adjust_RightDoorServo_Max
void Call_Adjust_WheelServo_Min() {
//Adjust Wheel servo Min
WheelServo_Min= EEPROM.get(12, WheelServo_Min); //Adres 12 + 13 = WheelServo_Min
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("W.servo Min= ");lcd.print(WheelServo_Min);
lcd.setCursor(0, 1); // X, Y
lcd.print("Select or - or +");
ButtonState = -1; // In case the Select switch is still pressed
//Set WheelServo_Min
while (ButtonState !=3) { // As long as not Select is pressed
ButtonState = Call_Read_ButtonState();
switch (ButtonState) {
case 1: // -
WheelServo_Min++;
break;
case 2: // +
WheelServo_Min--;
break;
};
WheelServo.write(WheelServo_Min);
lcd.setCursor(12, 0); // X, Y
if (WheelServo_Min < 1000) { lcd.print("0"); };
lcd.print(WheelServo_Min);
delay(KeyDelay);
};
EEPROM.put(12, WheelServo_Min); // Adres 12 and 13 = WheelServo_Min
} //Call_Adjust_WheelServo_Min
void Call_Adjust_FrontDoorServo_Min() {
//Adjust Frontdoor servo Min
FrontDoorServo_Min= EEPROM.get(0, FrontDoorServo_Min); //Adres 0 + 1 = FrontDoorServo_Min
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("F.door Min= ");lcd.print(FrontDoorServo_Min);
lcd.setCursor(0, 1); // X, Y
lcd.print("Select or - or +");
ButtonState = -1; // In case the Select switch is still pressed
//Set FrontDoorServo_Min
while (ButtonState !=3) { // As long as not Select is pressed
ButtonState = Call_Read_ButtonState();
switch (ButtonState) {
case 1: // -
FrontDoorServo_Min++;
break;
case 2: // +
FrontDoorServo_Min--;
break;
};
FrontDoorServo.write(FrontDoorServo_Min);
lcd.setCursor(12, 0); // X, Y
if (FrontDoorServo_Min < 1000) { lcd.print("0"); };
lcd.print(FrontDoorServo_Min);
delay(KeyDelay);
};
EEPROM.put(0, FrontDoorServo_Min); // Adres 0 and 1 = FrontDoorServo_Min
} //Call_Adjust_FrontDoorServo_Min
void Call_Adjust_LeftDoorServo_Min() {
//Adjust Leftdoor servo Min
LeftDoorServo_Min= EEPROM.get(4, LeftDoorServo_Min); //Adres 4 + 5 = LeftDoorServo_Min
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("L.door Min= ");lcd.print(LeftDoorServo_Min);
lcd.setCursor(0, 1); // X, Y
lcd.print("Select or - or +");
ButtonState = -1; // In case the Select switch is still pressed
//Set LeftDoorServo_Min
while (ButtonState !=3) { // As long as not Select is pressed
ButtonState = Call_Read_ButtonState();
switch (ButtonState) {
case 1: // -
LeftDoorServo_Min++;
break;
case 2: // +
LeftDoorServo_Min--;
break;
};
LeftDoorServo.write(LeftDoorServo_Min);
lcd.setCursor(12, 0); // X, Y
if (LeftDoorServo_Min < 1000) { lcd.print("0"); };
lcd.print(LeftDoorServo_Min);
delay(KeyDelay);
};
EEPROM.put(4, LeftDoorServo_Min); // Adres 6 and 7 = LeftDoorServo_Max
} //Call_Adjust_LeftDoorServo_Min
void Call_Adjust_RightDoorServo_Min() {
//Adjust Rightdoor servo Min
RightDoorServo_Min= EEPROM.get(8, RightDoorServo_Min); //Adres 8 + 9 = RightDoorServo_Min
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("R.door Min= ");lcd.print(RightDoorServo_Min);
lcd.setCursor(0, 1); // X, Y
lcd.print("Select or - or +");
ButtonState = -1; // In case the Select switch is still pressed
//Set RightDoorServo_Min
while (ButtonState !=3) { // As long as not Select is pressed
ButtonState = Call_Read_ButtonState();
switch (ButtonState) {
case 1: // -
RightDoorServo_Min++;
break;
case 2: // +
RightDoorServo_Min--;
break;
};
RightDoorServo.write(RightDoorServo_Min);
lcd.setCursor(12, 0); // X, Y
if (RightDoorServo_Min < 1000) { lcd.print("0"); };
lcd.print(RightDoorServo_Min);
delay(KeyDelay);
};
EEPROM.put(8, RightDoorServo_Min); // Adres 8 and 9 = RightDoorServo_Min
} //Call_Adjust_RightDoorServo_Min
void Call_Adjust_WheelServo_Max() {
//Adjust Wheel servo Max
WheelServo_Max = EEPROM.get(14, WheelServo_Max); //Adres 14 + 15 = WheelServo_Max
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("W.servo Max= ");lcd.print(WheelServo_Max);
lcd.setCursor(0, 1); // X, Y
lcd.print("Select or - or +");
ButtonState = -1; // In case the Select switch is still pressed
//Set WheelServo_Min
while (ButtonState !=3) { // As long as not Select is pressed
ButtonState = Call_Read_ButtonState();
switch (ButtonState) {
case 1: // -
WheelServo_Max++;
break;
case 2: // +
WheelServo_Max--;
break;
};
WheelServo.write(WheelServo_Max);
lcd.setCursor(12, 0); // X, Y
if (WheelServo_Max < 1000) { lcd.print("0"); };
lcd.print(WheelServo_Max);
delay(KeyDelay);
};
EEPROM.put(14, WheelServo_Max); // Adres 14 and 15 = WheelServo_Max
} //Call_Adjust_WheelServo_Max
void Call_Set_EepromToDefaultValues() {
lcd.clear();
lcd.setCursor(0, 0); // X, Y
lcd.print("Task: ");
lcd.setCursor(0, 1); // X, Y
lcd.print("Default settings");
//Delay time
for (int i=3; i>=0; i+=-1) {
lcd.setCursor(15, 0); // X, Y
lcd.print(i);
delay(1000);
};
unsigned int FrontDoorServo_Min = 1100;
EEPROM.put(0, FrontDoorServo_Min);
unsigned int FrontDoorServo_Max = 1900;
EEPROM.put(2, FrontDoorServo_Max);
unsigned int LeftDoorServo_Min = 1100;
EEPROM.put(4, LeftDoorServo_Min);
unsigned int LeftDoorServo_Max = 1900;
EEPROM.put(6, LeftDoorServo_Max);
unsigned int RightDoorServo_Min = 1100;
EEPROM.put(8, RightDoorServo_Min);
unsigned int RightDoorServo_Max = 1900;
EEPROM.put(10, RightDoorServo_Max );
unsigned int WheelServo_Min = 1100;
EEPROM.put(12, WheelServo_Min);
unsigned int WheelServo_Max = 1900;
EEPROM.put(14, WheelServo_Max);
} //Call_Set_EepromToDefaultValues
We leven in het midden van de ruimte, maar aan de rand van de tijd.
Advertisement
Re: Arduino NANO verliest programma
Wat zou ik moeten doen om de Arduino zijn programma te laten verliezen? Rare vraag he!
- Dat kan indien een programma in een loop zit dan lijkt het alsof er niets meer gebeurt.
- Als er in geheugen wordt geschreven wat niet de bedoeling is bv. met Array.
- Maar "meestal" gaat het goed dan geldt de Wet van Murphy: Als er iets fout kan gaan dan gaat het ook fout.
Ik heb snel door de code gekeken en het volgende valt mij op:
In de functie Call_IRQ_0 wordt de functie micros() gebruikt.
De waarde van deze functie wordt na ongeveer 70 minuten terug gezet op 0.
Dus het zou kunnen voorkomen dat SwitchEndPeriod kleinder is dan SwitchStartPeriod en
dan is SwitchPulseLength niet wat je verwacht!!
Of alles dan gewoon toch goed gaat heb ik niet bekeken maar het is makelijk te testen.
SwitchPulseLength = SwitchEndPeriod - SwitchStartPeriod;
if (SwitchEndPeriod < SwitchStartPeriod) { Serial.println("** BINGO **"); }
- Dat kan indien een programma in een loop zit dan lijkt het alsof er niets meer gebeurt.
- Als er in geheugen wordt geschreven wat niet de bedoeling is bv. met Array.
- Maar "meestal" gaat het goed dan geldt de Wet van Murphy: Als er iets fout kan gaan dan gaat het ook fout.
Ik heb snel door de code gekeken en het volgende valt mij op:
In de functie Call_IRQ_0 wordt de functie micros() gebruikt.
De waarde van deze functie wordt na ongeveer 70 minuten terug gezet op 0.
Dus het zou kunnen voorkomen dat SwitchEndPeriod kleinder is dan SwitchStartPeriod en
dan is SwitchPulseLength niet wat je verwacht!!
Of alles dan gewoon toch goed gaat heb ik niet bekeken maar het is makelijk te testen.
SwitchPulseLength = SwitchEndPeriod - SwitchStartPeriod;
if (SwitchEndPeriod < SwitchStartPeriod) { Serial.println("** BINGO **"); }
Re: Arduino NANO verliest programma
als ik het goed berijp dan trek je aan het stekkertje van de IIC en dan weet het programma niet meer waar hij bezig is, dus beter is het met een ingang aan/uit zetten
paul deelen
shooter@home.nl
shooter@home.nl
Re: Arduino NANO verliest programma
Beide bedankt voor het meedenken. Het is niet zo dat het IIC display onder spanning er uit wordt gehaald. Maar voordat de batterij wordt aangesloten. Ik zal een jumper maken die bepaald of er wel of geen display is aangesloten. Vanaf dan zou het goed moeten gaan.
Een ontvanger voor RC vliegtuigjes geeft een signaal met een frequentie van ongeveer 50 Hz af naar de servo's. Dat is een periodetijd van 20 mS. Het is de duty cycle die de stand van de servo bepaald. Dat geld voor alle kanalen zo. Call_IRQ_0 wordt dan ook nogal eens aangeroepen. Bij iedere opgaande, en neergaande flank. Dus daarop een overflow lijkt me onmogelijk.
Wat ik nou zo gek vind is dat bij een wederom aangesloten display, (zonder spanning he!) deze niet initialiseert. Eigenlijk trek ik daaaruit de conclusie dat het programma verdwenen is.
Nou ja, ik wil er verder niet te veel tijd aan besteden. Een extra jumer zou de boel moeten oplossen.
Bedankt voor het meedenken!
Een ontvanger voor RC vliegtuigjes geeft een signaal met een frequentie van ongeveer 50 Hz af naar de servo's. Dat is een periodetijd van 20 mS. Het is de duty cycle die de stand van de servo bepaald. Dat geld voor alle kanalen zo. Call_IRQ_0 wordt dan ook nogal eens aangeroepen. Bij iedere opgaande, en neergaande flank. Dus daarop een overflow lijkt me onmogelijk.
Wat ik nou zo gek vind is dat bij een wederom aangesloten display, (zonder spanning he!) deze niet initialiseert. Eigenlijk trek ik daaaruit de conclusie dat het programma verdwenen is.
Nou ja, ik wil er verder niet te veel tijd aan besteden. Een extra jumer zou de boel moeten oplossen.
Bedankt voor het meedenken!
We leven in het midden van de ruimte, maar aan de rand van de tijd.
Re: Arduino NANO verliest programma
Update:
I heb een jumper gemaakt met een pull down weerstand. Deze jumper zet een bool aan het begin van het programma. Als de bool false is, dan wordt het display niet geinitialiseerd, en ook geen data naar het display geschreven. Dat werkt allemaal prima. Toch verliest de NANO nog steeds soms het geheugen. Ik heb de NANO vervangen. Hiermee lijkt het probleem van geheugen verlies te zijn opgelost. Ik heb dat nog nooit meegemaakt.
I heb een jumper gemaakt met een pull down weerstand. Deze jumper zet een bool aan het begin van het programma. Als de bool false is, dan wordt het display niet geinitialiseerd, en ook geen data naar het display geschreven. Dat werkt allemaal prima. Toch verliest de NANO nog steeds soms het geheugen. Ik heb de NANO vervangen. Hiermee lijkt het probleem van geheugen verlies te zijn opgelost. Ik heb dat nog nooit meegemaakt.
We leven in het midden van de ruimte, maar aan de rand van de tijd.
Re: Arduino NANO verliest programma
Je programma heeft nog een instabiel gedeelte wat vooral zit in het gebruik van interrupt void Call_IRQ_0();
Een interrupt moet zo kort mogelijk duren en indien variabelen worden gebruikt moeten deze volatile worden gedeclareerd.
Door de compiler wordt deze variabele dan anders behandeld.
Voorbeeld voor aanpassingen in je programma;
- volatile variable opnemen waarmee wordt gemeld dat de interrupt heeft plaats gevonden. (newInterrupt)
- Begin van de loop de inhoud van Call_IRQ_0() opnemen.
- De inhoud van de Call_IRQ_0 wijzigen.
- de aanroepen van detachInterrupt(...); en attachInterrupt(...) zijn niet meer nodig.
Ik kan het natuurlijk niet testen maar hoop dat je er iets met de opmerkingen kan doen.
Een interrupt moet zo kort mogelijk duren en indien variabelen worden gebruikt moeten deze volatile worden gedeclareerd.
Door de compiler wordt deze variabele dan anders behandeld.
Voorbeeld voor aanpassingen in je programma;
- volatile variable opnemen waarmee wordt gemeld dat de interrupt heeft plaats gevonden. (newInterrupt)
- Code: Alles selecteren
volatile boolean newInterrupt = false;
bool SwitchNewSignal = false;
unsigned long SwitchStartPeriod = 0;
unsigned long SwitchEndPeriod = 0;
unsigned long SwitchPulseLength;
- Begin van de loop de inhoud van Call_IRQ_0() opnemen.
- Code: Alles selecteren
void loop() {
//flashing LED_BUILTIN
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
delay(100);
if (newInterrupt)
{
newInterrupt = false;
//This interrupt is called even when the signal go high or go low.
if (digitalRead(IRQ_0_pin) == HIGH) { //rising edge
SwitchStartPeriod = micros();
}
else { //falling edge
if (SwitchStartPeriod && (SwitchNewSignal == false)) {
SwitchEndPeriod = micros();
SwitchPulseLength = SwitchEndPeriod - SwitchStartPeriod;
SwitchStartPeriod = 0;
SwitchNewSignal = true;
}
}
}
.......
- De inhoud van de Call_IRQ_0 wijzigen.
- Code: Alles selecteren
void Call_IRQ_0()
{
newInterrupt = true;
}
- de aanroepen van detachInterrupt(...); en attachInterrupt(...) zijn niet meer nodig.
Ik kan het natuurlijk niet testen maar hoop dat je er iets met de opmerkingen kan doen.
Re: Arduino NANO verliest programma
@ThHe
Bedankt voor je opmerking. Dat is een wel hele korte inhoud van de interupt routine! Maar goed, als dat beter is, dan vind ik dat prima. Dat "volatile boolean" heb ik nog niet goed begrepen. Ik heb het wel gelezen voordat ik de interupt routine maakte. Maar goed, als dat zo moet, dan zal ik dat doen. Het project is inmiddels aan de modelbouwer geleverd. Dus hij gaat er nu mee spelen. Dat leveren ging ook niet bepaald zonder slag of stoot. Het programm vertoonde extreem vreemd gedrag. Zoals een for lus die er halverwege mee ophield. Dit is niet eens mogelijk. Maar ik heb het toch echt gezien. Op enig moment bedachten we dat het EMC problemen zouden kunnen zijn. Een condensator over de 5V aansluiting loste dit op. Dan weer een vraag of de arduino op 26V ook zal werken. Ehh, ja, ik denk het wel...
Hiermee toonden we aan dat elektriciteit op rook werkt. Immers, als het kapot gaat, dan komt er rook uit!
Toch nog even over die interupt. Eigenlijk begrijp ik nog niet goed waarom die routine zo kort mogelijk moet zijn. Immers, als ik in die routine zit, dan blokker ik de boel. En pas als ik de routine weer vrijgeef, dan mag de volgende interupt komen. Misschien dat je daar nog eens een paar woorden aan kan wijden?
Bedankt voor je opmerking. Dat is een wel hele korte inhoud van de interupt routine! Maar goed, als dat beter is, dan vind ik dat prima. Dat "volatile boolean" heb ik nog niet goed begrepen. Ik heb het wel gelezen voordat ik de interupt routine maakte. Maar goed, als dat zo moet, dan zal ik dat doen. Het project is inmiddels aan de modelbouwer geleverd. Dus hij gaat er nu mee spelen. Dat leveren ging ook niet bepaald zonder slag of stoot. Het programm vertoonde extreem vreemd gedrag. Zoals een for lus die er halverwege mee ophield. Dit is niet eens mogelijk. Maar ik heb het toch echt gezien. Op enig moment bedachten we dat het EMC problemen zouden kunnen zijn. Een condensator over de 5V aansluiting loste dit op. Dan weer een vraag of de arduino op 26V ook zal werken. Ehh, ja, ik denk het wel...
Hiermee toonden we aan dat elektriciteit op rook werkt. Immers, als het kapot gaat, dan komt er rook uit!
Toch nog even over die interupt. Eigenlijk begrijp ik nog niet goed waarom die routine zo kort mogelijk moet zijn. Immers, als ik in die routine zit, dan blokker ik de boel. En pas als ik de routine weer vrijgeef, dan mag de volgende interupt komen. Misschien dat je daar nog eens een paar woorden aan kan wijden?
We leven in het midden van de ruimte, maar aan de rand van de tijd.
Re: Arduino NANO verliest programma
Een interrupt verstoort de gang van zaken in een programma.
Een interrupt stopt de programma code en gaat zelf aan de gang maar de programma code kan instabiel worden indien dat te lang duurt en zeker
als er nog variabelen door de interrupt code worden gemuteerd.
Daarom moet altijd overbodige code in de interrupt functie worden vermeden.
In jouw code werd digitalRead uitgevoerd en I/O functies kosten naar verhouding veel tijd.
Verder worden variabelen van het programma gemuteerd en er is geen garantie dat het programma daar toevallig ook mee bezig is.
In geval van jouw programma:
Buiten het ophalen van digitalRead(IRQ_0_pin) worden de variabelen Switch... gemuteerd.
Deze worden alleen in de loop gebruikt.
Dus een signaal van het interrupt voert nu de digitalRead(IRQ_0_pin) uit en muteert de variabelen.
Direct na de mutatie worden ze dan gebuikt in de volgende statements van de loop.
Voordeel is dat het signaal snel gezet is en read en mutatie alleen wordt uitgevoerd als je de variabelen nodig hebt.
Nu nog het keyword volatile:
Een normaal programma zal zijn variabelen steeds muteren door gebruik te maken van zogenaamde registers.
Dus de inhoud wordt naar een register gezet en een evenuele wijziging in het register wordt teruggeschreven naar de variabelen.
Als er een interrupt wordt verwerkt kunnen er dus variablen zijn die in het register aan het muteren zijn.
Om dit te voorkomen wordt door het keyword volatile door de compiler deze variabelen in RAM verwerkt en dat voorkomt dat probleem.
Dus alle variabelen in een interrupt binnen de scope van het programma voorzien van volatile.
Een interrupt stopt de programma code en gaat zelf aan de gang maar de programma code kan instabiel worden indien dat te lang duurt en zeker
als er nog variabelen door de interrupt code worden gemuteerd.
Daarom moet altijd overbodige code in de interrupt functie worden vermeden.
In jouw code werd digitalRead uitgevoerd en I/O functies kosten naar verhouding veel tijd.
Verder worden variabelen van het programma gemuteerd en er is geen garantie dat het programma daar toevallig ook mee bezig is.
In geval van jouw programma:
Buiten het ophalen van digitalRead(IRQ_0_pin) worden de variabelen Switch... gemuteerd.
Deze worden alleen in de loop gebruikt.
Dus een signaal van het interrupt voert nu de digitalRead(IRQ_0_pin) uit en muteert de variabelen.
Direct na de mutatie worden ze dan gebuikt in de volgende statements van de loop.
Voordeel is dat het signaal snel gezet is en read en mutatie alleen wordt uitgevoerd als je de variabelen nodig hebt.
Nu nog het keyword volatile:
Een normaal programma zal zijn variabelen steeds muteren door gebruik te maken van zogenaamde registers.
Dus de inhoud wordt naar een register gezet en een evenuele wijziging in het register wordt teruggeschreven naar de variabelen.
Als er een interrupt wordt verwerkt kunnen er dus variablen zijn die in het register aan het muteren zijn.
Om dit te voorkomen wordt door het keyword volatile door de compiler deze variabelen in RAM verwerkt en dat voorkomt dat probleem.
Dus alle variabelen in een interrupt binnen de scope van het programma voorzien van volatile.
Re: Arduino NANO verliest programma
@ThHe, bedankt voor de uitleg!
We leven in het midden van de ruimte, maar aan de rand van de tijd.
9 berichten
• Pagina 1 van 1
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 60 gasten