Hallo Freunde des Arduino,
ich möchte gerne ein Servo über den Arduino Nano (atmega328 nano) steuern. Dazu habe ich noch eine Zeitsteuerung, die läuft und ein paar Schalter, die das Servo und die Zeit im Display steuern sollen.
Nun habe ich das Problem, dass ich das ungeordnete Bewegungen macht und dann das Programm stillsteht. manchmal passiert das gleich wenn ich das Programm starte, manchmal nach ein paar mal Servo + und -. Beim UNO hatte ich das Problem nur, wenn ich für das Servo eine seperate Stromquelle hatte, über die PINs lief es fehlerfrei. Kann das etwas mit dem Timer (millis()) zu tun haben.
Hier mein Code, vielleicht weiß jemand eine Lösung:
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // I2C address 0x27, 20 column and 4 rows
String empfangBT;
int servoPos = 160;
int servoPosMax = 150;
int servoPosMin = 20;
int servoDelta = 10;
int timeCode = 0;
long zeit;
Servo myservo;
const byte buttonPinA = 4; //Speed
const byte buttonPinB = 5; //Ergo+
const byte buttonPinC = 6; //Ergo-
const byte buttonPinD = 3; //resetTime
const byte buttonPinE = 7; //Pause-Time
unsigned long lastPressedTime = 0;
long millsD=0;
double deltaT=0;
double deltaT1=0;
//alle 5 Durchläufe wird Geschwindigkeit und Puls gesendet
int sending = 0;
int sendingCount = 5;
double diffsumme =0 ;
double strecke = 0;
float Quellspannung=5.0;
int AnalogPin=3;
int R1=1500.0; //Wert des bekannten Widerstands (der mitgelieferte 1,5k-Widerstand)
long MesswertHf;
float SpannungR2; //Spannung über dem zu messenden Widerstand
float WiderstandHf;
long myTimer = 0;
long myTimeout = 1000;
boolean pause = false;
void setup(){
Serial.begin(9600); //serieller Monitor wird gestartet, Baudrate auf 9600 festgelegt
pinMode(buttonPinA, INPUT_PULLUP);
pinMode(buttonPinB, INPUT_PULLUP);
pinMode(buttonPinC, INPUT_PULLUP);
pinMode(buttonPinD, INPUT_PULLUP);
pinMode(buttonPinE, INPUT_PULLUP);
lcd.init(); // initialize the lcd
lcd.backlight();
myservo.attach(9);
myservo.write(servoPos);
Serial.println("s170#");
dPrint(0,0,"**** Ergometer *****");
dPrint(0,1,"Stufe:");
dPrint(0,2,"Speed:");
dPrint(0,3,"Time:");
}
void loop(){
//Serielle Daten empfangen
while(Serial.available() > 0) {
empfangBT=Serial.readStringUntil('\n');
}
if (millies() > myTimeout + myTimer ) {
int sekunde = (millies()/1000) % 60; // Das Zeichen: "%" ist der Modulo-Operator
int minute = (millies()/60000) % 60;
int stunde = (millies()/3600000) % 24;
//Stunde
if (stunde<10)
{
dPrint(7,3, "0");
dPrint(8,3, String(stunde));
}
else
{
dPrint(7,3, String(stunde));
}
dPrint(9,3, ":");
//Minute
if (minute<10)
{
dPrint(10,3, "0");
dPrint(11,3, String(minute));
}
else
{
dPrint(10,3, String(minute));
}
dPrint(12,3, ":");
//Sekunde
if (sekunde<10)
{
dPrint(13,3, "0");
dPrint(14,3, String(sekunde));
}
else
{
dPrint(13,3, String(sekunde));
}
// dPrint(7,3, " ");
// dPrint(7,3, String(myTimer/1000));
myTimer = millies();
}
//Servosteuerung
if(empfangBT.indexOf("x")!=-1){
int posX = empfangBT.indexOf("x");
int posH = empfangBT.indexOf("#");
String out = empfangBT.substring(posX+1,posH);
servoPos = out.toInt();
//myservo.write(servoPos);
String sb = "s";
String sPos = String(servoPos);
String hash = "#";
String zuSenden = sb+sPos+hash;
dPrint(7, 1, " ");
dPrint(7, 1, String(servoPos));
myservo.write(servoPos);
Serial.println(zuSenden);
empfangBT="";
}
//Geschwindigkeit ermitteln
if (buttonPressedA()){
if (lastPressedTime > 0){
unsigned long difference = millies()-lastPressedTime;
// Serial.print("Time difference: ");
// Serial.println(difference);
diffsumme=diffsumme+difference;
if(sending>=sendingCount){
float sendeSpeed = (diffsumme/sending)/1000;
dSendFloat("v", "#", sendeSpeed);
double umfang = 2 * 0.2 * 3.141;
double speed = (umfang / sendeSpeed) * 3.6;
String s1 = String(speed);
String s2 = " km/h";
String sx = s1+s2;
sending=0;
diffsumme=0;
dPrint(7, 2, " ");
dPrint(7, 2, sx);
//in sec
deltaT1= (millies()-deltaT)/1000;
strecke = (((deltaT1)/3600)*speed)+strecke;
dPrint(11, 1, " ");
dPrint(12, 1, String(strecke));
dPrint(17, 1, "km");
deltaT=millies();
}
sending++;
}
lastPressedTime = millies();
}
if (buttonPressedB()){
if(servoPos<servoPosMax){
servoPos+=10;
//myservo.write(servoPos);
String sb = "s";
String sPos = String(servoPos);
String hash = "#";
String zuSenden = sb+sPos+hash;
myservo.write(servoPos);
Serial.println(zuSenden);
dPrint(7, 1, " ");
dPrint(7, 1, String(servoPos));
}
}
if (buttonPressedC()){
if(servoPos>servoPosMin){
servoPos-=10;
//myservo.write(servoPos);
String sb = "s";
String sPos = String(servoPos);
String hash = "#";
String zuSenden = sb+sPos+hash;
myservo.write(servoPos);
Serial.println(zuSenden);
dPrint(7, 1, " ");
dPrint(7, 1, String(servoPos));
}
}
//Time-Reset
if (buttonPressedD()){
millsD=millis();
strecke=0;
dPrint(11, 1, " ");
dPrint(12, 1, String(strecke));
dPrint(17, 1, "km");
myTimer = 0;
}
//Time-Pause
if (buttonPressedE()){
millsD=millis();
myTimer = 0;
}
MesswertHf=0;
for(int i=0;i<5;i++){
MesswertHf+=analogRead(AnalogPin);
}
MesswertHf=trunc(MesswertHf/5);
SpannungR2=(Quellspannung/1023.0)*MesswertHf;
WiderstandHf=R1*(SpannungR2/(Quellspannung-SpannungR2));
}
boolean buttonPressedA(){
static unsigned long lastChange = 0;
static byte lastState = LOW;
static byte state;
byte actState = digitalRead(buttonPinA);
if (actState != lastState) {
lastState = actState;
lastChange = millis();
}
if (state != actState && millis()-lastChange > 20){
state = actState;
return !state; // Returns true only when state changes from HIGH to LOW
}
return false;
}
boolean buttonPressedB(){
static unsigned long lastChange = 0;
static byte lastState = LOW;
static byte state;
byte actState = digitalRead(buttonPinB);
if (actState != lastState) {
lastState = actState;
lastChange = millis();
}
if (state != actState && millis()-lastChange > 20){
state = actState;
return !state; // Returns true only when state changes from HIGH to LOW
}
return false;
}
boolean buttonPressedC(){
static unsigned long lastChange = 0;
static byte lastState = LOW;
static byte state;
byte actState = digitalRead(buttonPinC);
if (actState != lastState) {
lastState = actState;
lastChange = millis();
}
if (state != actState && millis()-lastChange > 20){
state = actState;
return !state; // Returns true only when state changes from HIGH to LOW
}
return false;
}
boolean buttonPressedD(){
static unsigned long lastChange = 0;
static byte lastState = LOW;
static byte state;
byte actState = digitalRead(buttonPinD);
if (actState != lastState) {
lastState = actState;
lastChange = millis();
}
if (state != actState && millis()-lastChange > 20){
state = actState;
return !state; // Returns true only when state changes from HIGH to LOW
}
return false;
}
boolean buttonPressedE(){
static unsigned long lastChange = 0;
static byte lastState = LOW;
static byte state;
byte actState = digitalRead(buttonPinE);
if (actState != lastState) {
lastState = actState;
lastChange = millis();
}
if (state != actState && millis()-lastChange > 20){
state = actState;
return !state; // Returns true only when state changes from HIGH to LOW
}
return false;
}
void dPrint(int zeile, int spalte, String text){
lcd.setCursor(zeile,spalte);
lcd.print(text);
}
void dSendFloat(String vor, String nach, float meldung){
String zuSendenX = vor+String(meldung)+nach;
//dPrint(10,2,String(zuSendenX));
Serial.println(zuSendenX);
}
void dSendString(String vor, String nach, String meldung){
String zuSendenX = vor+meldung+nach;
dPrint(10,3,String(zuSendenX));
Serial.println(zuSendenX);
}
long millies(){
return millis()-millsD;
}