From 3d38ab4b4fb6fa87c9ea7b9233652ea58ac5ee76 Mon Sep 17 00:00:00 2001 From: nickg <132455a@gmail.com> Date: Wed, 5 Feb 2020 15:51:52 +0100 Subject: [PATCH 1/8] Moved measurement to robot instaed of RC. --- Code/miniRobot/miniRobot.ino | 17 +++++++++++++++++ .../temperatureDistance.ino | 0 Code/miniRobotRC/_main.ino | 18 +----------------- 3 files changed, 18 insertions(+), 17 deletions(-) rename Code/{miniRobotRC => miniRobot}/temperatureDistance.ino (100%) diff --git a/Code/miniRobot/miniRobot.ino b/Code/miniRobot/miniRobot.ino index c05a9f1..ee410b6 100644 --- a/Code/miniRobot/miniRobot.ino +++ b/Code/miniRobot/miniRobot.ino @@ -12,6 +12,7 @@ RF24 radio(A0, 3); // CE, CSN byte commands[32]; //byte 0 = command +long timer; void inline clearCommands() { for(uint8_t i=0; i<32; i++) { @@ -72,6 +73,11 @@ void setup() { radio.setPALevel(RF24_PA_MAX); radio.startListening(); clearCommands(); + + //Temperatur- und Abstandsmessung + tempDistSetup(); + setEchoPins(0, 0); //Setze die pins für den Abstandsensor aus denen gelesenw erden soll das erster ist der Trigger-, das zweite der Echopin + timer = millis(); } void loop() { @@ -86,6 +92,17 @@ void loop() { } drive.setPWM_A(pwmA); drive.setPWM_B(pwmB); + + //Temperatur- und Abstandsmessung + + temperature = dallas(4, 0); + + if(millis() - timer >= 100){ + measureDistance(); + timer = millis(); + } + + distance = calculateDistance(); } void commandInterpretation() { diff --git a/Code/miniRobotRC/temperatureDistance.ino b/Code/miniRobot/temperatureDistance.ino similarity index 100% rename from Code/miniRobotRC/temperatureDistance.ino rename to Code/miniRobot/temperatureDistance.ino diff --git a/Code/miniRobotRC/_main.ino b/Code/miniRobotRC/_main.ino index e851f94..27a1c49 100644 --- a/Code/miniRobotRC/_main.ino +++ b/Code/miniRobotRC/_main.ino @@ -2,8 +2,6 @@ #include #include -long timer; - void inline clearCommands() { for(uint8_t i=0; i<32; i++) { commands[i] = 0xFF; @@ -17,10 +15,7 @@ void setup() { driveTimeout = 10; joystickInit(); //TODO clearCommands(); - //Temperatur- und Abstandsmessung - tempDistSetup(); - setEchoPins(0, 0); //Setze die pins für den Abstandsensor aus denen gelesenw erden soll das erster ist der Trigger-, das zweite der Echopin - timer = millis(); + } void loop() { @@ -38,17 +33,6 @@ void loop() { } tasten.clearButton(buttonStart); - //Temperatur- und Abstandsmessung - - temperature = dallas(4, 0); - - if(millis() - timer >= 100){ - measureDistance(); - timer = millis(); - } - - distance = calculateDistance(); - } void lcdMenu() { From b777bca88d1157c4b1de758a7bf604fa96eaa692 Mon Sep 17 00:00:00 2001 From: nickg <132455a@gmail.com> Date: Wed, 5 Feb 2020 17:23:46 +0100 Subject: [PATCH 2/8] Fixed some issues. --- Code/miniRobot/miniRobot.ino | 9 ++++++--- Code/miniRobot/temperatureDistance.ino | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Code/miniRobot/miniRobot.ino b/Code/miniRobot/miniRobot.ino index fec1642..53de7dd 100644 --- a/Code/miniRobot/miniRobot.ino +++ b/Code/miniRobot/miniRobot.ino @@ -13,6 +13,8 @@ RF24 radio(A0, 3); // CE, CSN byte commands[32]; //byte 0 = command long timer; +int temperature; +int distance = 0; void inline clearCommands() { for(uint8_t i=0; i<32; i++) { @@ -31,7 +33,7 @@ const byte address[6] = "00001"; #define stopDrive 6 //stop #define getTemp 7 //get temperature #define timeToDrive 8 //Zeitdauer des fahrens -#define distance 10 //Abstand zu Objekten +#define getDistance 10 //Abstand zu Objekten //Motortreiber //#include @@ -148,8 +150,9 @@ void commandInterpretation() { break; } case getTemp : { - temperatur = (0xFF00 & (commands[i+1] << 8)); - temperatur |= (0x00FF & commands[i+2]); + int temp5; + temp5 = (0xFF00 & (commands[i+1] << 8)); + temp5 |= (0x00FF & commands[i+2]); break; } case timeToDrive : { diff --git a/Code/miniRobot/temperatureDistance.ino b/Code/miniRobot/temperatureDistance.ino index 637be31..625019a 100644 --- a/Code/miniRobot/temperatureDistance.ino +++ b/Code/miniRobot/temperatureDistance.ino @@ -41,7 +41,6 @@ void measureDistance(){ delayMicroseconds(10); // ... put the trigger down ... - distance = 600; PORTD &= ~(1< Date: Thu, 6 Feb 2020 09:50:08 +0100 Subject: [PATCH 3/8] Added some tex for ds1820. --- Latex/main.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Latex/main.tex b/Latex/main.tex index b2ba9c7..c81c082 100644 --- a/Latex/main.tex +++ b/Latex/main.tex @@ -211,7 +211,7 @@ Da das Array eine feste Größe von 32 Byte hat, lassen sich folglich bis zu 10 \end{file} Damit sind bereits Sämtliche Konfigurationen für die Hardware-SPI Kommunikation zwischen Arduino nano und dem nRF24L01 erledigt. - Kommunizieren zwischen zwei dieser Setups wird dann durch die Funktionen read und wirite, jedoch muss vor dem Start einer Kommunikation die Methode begin() aufgerufen werden. + Kommunizieren zwischen zwei dieser Setups wird dann durch die Funktionen read und write, jedoch muss vor dem Start einer Kommunikation die Methode begin() aufgerufen werden. \begin{file}[RF24 initialisieren] \begin{lstlisting}[language=C++] //An der Sender Seite @@ -243,7 +243,9 @@ Da das Array eine feste Größe von 32 Byte hat, lassen sich folglich bis zu 10 %Folgende beiden ließen sich auch durch subsections mittels sensoric als section realisieren, kommt aber auf die menge des textes an subsections sollten nicht über eine halbe seite lang sein. \newpage \section{Thermosensor} %Nick - + Wie bereits erwähnt benutzen wir einen Dallas DS1820 1-Wire Digital Thermometer, um die Motortemperatur zu messen. Der DS1820 speichert die Temperatur als einen 9bit Wert und kann Temperaturen im Bereich von -55°C bis 125°C messen. Für unsere Bedürfnisse reicht es wenn wir in 1-er Schritten messen. Der Sensor kommt aber auch mit halben Graden zu recht. + + Eine Messung wird durchgeführt indem der Sensor Takte, innerhalb eines Zeitfensters zählt. Der Zähler startet bei einem Wert, der -55°C darstellt. Erreicht der Zähler 0 schneller als das vorgegebene Zeitfenster wird das Temperaturregister inkrementiert. Der Zähler wird auf einen vom Slope Accumulator Circuitry abhängigen wert gestellt und wieder runtergezählt. Dies wiederholt sich solange bis das festgelegte Zeitfenster abgelaufen ist. \newpage \section{Ultraschallsensor} %Nick From 80eb9f8ab4e29a4e983df851d375d99f2f60e290 Mon Sep 17 00:00:00 2001 From: Yves Ehrlich Date: Fri, 7 Feb 2020 21:52:36 +0100 Subject: [PATCH 4/8] LCD Darstellung geaendert, jetzt alle 100ms refresh der 6 Zeilen --- .~lock.ideen_mechanik_und_elektronik.odt# | 2 +- Code/miniRobotRC/fahrsteuerung_old.ino | 15 +++------ Code/miniRobotRC/interruptRoutinen.ino | 5 +++ Code/miniRobotRC/joystick.ino | 36 ++++++---------------- Code/miniRobotRC/miniRobotRC.ino | 33 +++++--------------- ideen_mechanik_und_elektronik.odt | Bin 24755 -> 25147 bytes 6 files changed, 27 insertions(+), 64 deletions(-) diff --git a/.~lock.ideen_mechanik_und_elektronik.odt# b/.~lock.ideen_mechanik_und_elektronik.odt# index affc95a..0e6d32f 100644 --- a/.~lock.ideen_mechanik_und_elektronik.odt# +++ b/.~lock.ideen_mechanik_und_elektronik.odt# @@ -1 +1 @@ -,yves,yves-UB,05.02.2020 13:15,file:///home/yves/.config/libreoffice/4; \ No newline at end of file +,yves,yves-UB,05.02.2020 13:51,file:///home/yves/.config/libreoffice/4; \ No newline at end of file diff --git a/Code/miniRobotRC/fahrsteuerung_old.ino b/Code/miniRobotRC/fahrsteuerung_old.ino index 915b3ba..ec64ad8 100644 --- a/Code/miniRobotRC/fahrsteuerung_old.ino +++ b/Code/miniRobotRC/fahrsteuerung_old.ino @@ -3,35 +3,30 @@ void manualDigitalDrive() { // while(!tasten.getButtonCycle(buttonL1)) { clearCommands(); if(!tasten.getAnyPressed()) { - lcd.clear(); - lcd.println("Warte..."); + lcdLines[0] = "Warte..."; } if(tasten.checkButton(buttonB) || tasten.checkButton(buttonUp)) { pwmA = -215; pwmB = -255; - lcd.clear(); - lcd.println("geradeaus fahren"); + lcdLines[0] = "geradeaus fahren"; goOn =true; } if(tasten.checkButton(buttonC) || tasten.checkButton(buttonDown)) { pwmA = 100; pwmB = 255; - lcd.clear(); - lcd.println("rueckwaerts fahren"); + lcdLines[0] = "rueckwaerts fahren"; goOn =true; } if(tasten.checkButton(buttonRight)) { pwmA = -100; //rechter Motor pwmB = 100; - lcd.clear(); - lcd.println("rechts lenken"); + lcdLines[0] = "rechts lenken"; goOn =true; } if(tasten.checkButton(buttonLeft)) { pwmB = -100; pwmA = 100; - lcd.clear(); - lcd.println("links lenken"); + lcdLines[0] = "links lenken"; goOn =true; } if(goOn) { diff --git a/Code/miniRobotRC/interruptRoutinen.ino b/Code/miniRobotRC/interruptRoutinen.ino index cce5cf5..09ca807 100644 --- a/Code/miniRobotRC/interruptRoutinen.ino +++ b/Code/miniRobotRC/interruptRoutinen.ino @@ -3,6 +3,11 @@ ISR(TIMER2_COMPA_vect) { tasten.checkButtons(); renderTime++; if(renderTime >= renderTimeout) { + lcd.clear(); + for(uint8_t i = 0; i < sizeof(lcdLines); i++) { + lcd.gotoXY(0, i); + lcd.print(lcdLines[i]); + } lcd.renderAll(); renderTime = 0; } diff --git a/Code/miniRobotRC/joystick.ino b/Code/miniRobotRC/joystick.ino index 70d8392..c2329e2 100644 --- a/Code/miniRobotRC/joystick.ino +++ b/Code/miniRobotRC/joystick.ino @@ -10,28 +10,8 @@ volatile int16_t yValue = 0; volatile int16_t leftPWM = 0; volatile int16_t rightPWM = 0; -const int16_t deadZone = 10; -/* -void setup() { - Serial.begin(115200); -} - -void loop() { - koordinaten(analogRead(xPin), analogRead(yPin)); - motorPWM(); - Serial.print("X: "); - Serial.println(xValue); - Serial.print("Y: "); - Serial.println(yValue); - Serial.print("links: "); - Serial.println(leftPWM); - Serial.print("rechts: "); - Serial.println(rightPWM); - - delay(200); +const int16_t deadZone = 40; -} -*/ void motorMapping() { static long temp = millis(); koordinaten(analogRead(xPin), analogRead(yPin)); @@ -40,12 +20,14 @@ void motorMapping() { pwmB = map(leftPWM, -255,255,leftMin,leftMax); pwmA = map(rightPWM, -255,255,rightMin,rightMax); if((millis() - temp) > 100) { - lcd.clear(); - lcd.println("Links: "); - lcd.println(pwmB); - lcd.gotoXY(0,2); - lcd.println("Rechts: "); - lcd.println(pwmA); + // lcd.clear(); + // lcd.println("Links: "); + lcdLines[0] = "Links: " + String(pwmB, DEC); + // lcd.println(pwmB); + // lcd.gotoXY(0,2); + // lcd.println("Rechts: "); + lcdLines[0] = "Rechts: " + String(pwmA, DEC); + // lcd.println(pwmA); } senden(); diff --git a/Code/miniRobotRC/miniRobotRC.ino b/Code/miniRobotRC/miniRobotRC.ino index 898b88b..038a595 100644 --- a/Code/miniRobotRC/miniRobotRC.ino +++ b/Code/miniRobotRC/miniRobotRC.ino @@ -4,7 +4,7 @@ #define CLR_BIT(p,n) ((p) &= ~((1) << (n))) #define SET_BIT(p,n) ((p) |= (1 << (n))) - +//Pinzuordnungen #define BL 10 //backlight, Hintergrundbeleuchtung LCD #define SD_CARD_CS 2 //D2 ist Chip Enable #define BAT_VOLTAGE A7 //Akkuspannung an A7 @@ -17,7 +17,8 @@ volatile myInterrupts pwmBL; volatile shiftRegButton tasten; //LCD uint8_t renderTime = 0; -#define renderTimeout 100 +#define renderTimeout 100 //es wird alle 100ms gerendert +String lcdLines[6]; //Strings welche alle 100ms ausgegeben werden //Kommandos #define nothing 9 //reset/nichts tun @@ -31,15 +32,15 @@ uint8_t renderTime = 0; #define timeToDrive 8 //Zeitdauer des fahrens #define getDistance 10 //Abstand zu Objekten -int pwmA = 0; -int pwmB = 0; +int16_t pwmA = 0; +int16_t pwmB = 0; bool forwardA = true; bool forwardB = true; bool driveOn = false; uint16_t driveTimeout = 0; -int distance; -int temperature; +int16_t distance; +int16_t temperature; //Funk #include @@ -51,23 +52,3 @@ RF24 radio(A2, A3); // CE, CSN const byte address[6] = "00001"; uint8_t commands[32]; -/* -const String mainMenu[] = { - "fahren", //0 - "stoppen", //1 - "manuell fahren", //2 - "", //3 - "", //4 - "", //5 - "", //6 - "", //7 - "", //8 - "" //9 -}; - -const String subMenuEntry0[] = { - "Zeitdauer", - "Speed A", - "Speed B", - "Starten" -}; */ diff --git a/ideen_mechanik_und_elektronik.odt b/ideen_mechanik_und_elektronik.odt index dd56f823822177fb17c31c6d4197bc69fbbff4a7..769050297aa9d58111cae8e6588f5816f21619af 100644 GIT binary patch delta 20512 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 delta 20153 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 Date: Sat, 8 Feb 2020 01:36:32 +0100 Subject: [PATCH 5/8] Fixed temperature measurement. --- Code/miniRobot/miniRobot.ino | 16 ++++++++-------- Code/miniRobot/temperatureDistance.ino | 12 +++++++----- Code/miniRobotRC/_main.ino | 1 - Code/miniRobotRC/fahrsteuerung_old.ino | 5 +++++ Code/miniRobotRC/miniRobotRC.ino | 2 +- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Code/miniRobot/miniRobot.ino b/Code/miniRobot/miniRobot.ino index 53de7dd..4f94f72 100644 --- a/Code/miniRobot/miniRobot.ino +++ b/Code/miniRobot/miniRobot.ino @@ -13,7 +13,7 @@ RF24 radio(A0, 3); // CE, CSN byte commands[32]; //byte 0 = command long timer; -int temperature; +int16_t temperature; int distance = 0; void inline clearCommands() { @@ -78,7 +78,7 @@ void setup() { //Temperatur- und Abstandsmessung tempDistSetup(); - setEchoPins(0, 0); //Setze die pins für den Abstandsensor aus denen gelesenw erden soll das erster ist der Trigger-, das zweite der Echopin + setEchoPins(16, 5); //16: A2, 5: D5 timer = millis(); } @@ -100,8 +100,8 @@ void loop() { temperature = dallas(4, 0); if(millis() - timer >= 100){ - measureDistance(); - timer = millis(); + measureDistance(); + timer = millis(); } distance = calculateDistance(); @@ -149,10 +149,9 @@ void commandInterpretation() { driveOn = false; break; } - case getTemp : { - int temp5; - temp5 = (0xFF00 & (commands[i+1] << 8)); - temp5 |= (0x00FF & commands[i+2]); + case getTemp : { + + radio.write(&temperature, sizeof(temperature)); break; } case timeToDrive : { @@ -169,6 +168,7 @@ void commandInterpretation() { forwardA = true; forwardB = true; driveOn = false; */ + break; } } diff --git a/Code/miniRobot/temperatureDistance.ino b/Code/miniRobot/temperatureDistance.ino index 625019a..216f1dd 100644 --- a/Code/miniRobot/temperatureDistance.ino +++ b/Code/miniRobot/temperatureDistance.ino @@ -36,13 +36,13 @@ int calculateDistance(){ void measureDistance(){ - PORTD |= (1< From ebed7f2188c5d138653ec38b55837da9c5004966 Mon Sep 17 00:00:00 2001 From: nickg <132455a@gmail.com> Date: Sat, 8 Feb 2020 18:55:40 +0100 Subject: [PATCH 6/8] Temperature is now shown on the lcd! Amazing! Wow, very cool. --- Code/miniRobot/miniRobot.ino | 19 +++++++++++++------ Code/miniRobotRC/JoystickSteuerung.ino | 6 ------ Code/miniRobotRC/_main.ino | 4 +++- Code/miniRobotRC/fahrsteuerung_old.ino | 25 +++++++++++++++++++++++++ Code/miniRobotRC/funkInit.ino | 2 ++ Code/miniRobotRC/miniRobotRC.ino | 3 +++ 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/Code/miniRobot/miniRobot.ino b/Code/miniRobot/miniRobot.ino index 4f94f72..bb40118 100644 --- a/Code/miniRobot/miniRobot.ino +++ b/Code/miniRobot/miniRobot.ino @@ -23,6 +23,7 @@ void inline clearCommands() { } const byte address[6] = "00001"; +const byte address2[6] = "00002"; //Kommandos #define nothing 9 //reset/nichts tun #define speedA 1 // set speed A + speed @@ -60,7 +61,7 @@ bool forwardA = true; bool forwardB = true; volatile bool driveOn = false; -int temperatur = 0; +int16_t temperatur = 0; volatile long driveTimeout = 0; @@ -71,6 +72,7 @@ void setup() { // motorA.setPWM16(2,RESOLUTION); // motorB.setPWM16(2,RESOLUTION); radio.begin(); + radio.openWritingPipe(address2); radio.openReadingPipe(0, address); radio.setPALevel(RF24_PA_MAX); radio.startListening(); @@ -83,6 +85,7 @@ void setup() { } void loop() { + Serial.println(temperature); if (radio.available()) { radio.read(&commands, sizeof(commands)); commandInterpretation(); @@ -92,16 +95,18 @@ void loop() { pwmA = 0; pwmB = 0; } + drive.setPWM_A(pwmA); drive.setPWM_B(pwmB); - + + //Temperatur- und Abstandsmessung temperature = dallas(4, 0); if(millis() - timer >= 100){ - measureDistance(); - timer = millis(); + measureDistance(); + timer = millis(); } distance = calculateDistance(); @@ -150,8 +155,10 @@ void commandInterpretation() { break; } case getTemp : { - - radio.write(&temperature, sizeof(temperature)); + Serial.println("Senden!"); + radio.stopListening(); + radio.write(&temperature, sizeof(int16_t)); + radio.startListening(); break; } case timeToDrive : { diff --git a/Code/miniRobotRC/JoystickSteuerung.ino b/Code/miniRobotRC/JoystickSteuerung.ino index 6c03c41..42b7304 100644 --- a/Code/miniRobotRC/JoystickSteuerung.ino +++ b/Code/miniRobotRC/JoystickSteuerung.ino @@ -64,11 +64,5 @@ void joystickInit() { commands[7] = highByte(driveTimeout); commands[8] = lowByte(driveTimeout); commands[9] = goDrive; - commands[10] = getTemp; - commands[11] = highByte(temperature); - commands[12] = lowByte(temperature); - commands[13] = getTemp; - commands[14] = highByte(distance); - commands[15] = lowByte(distance); radio.write(&commands, sizeof(commands)); } diff --git a/Code/miniRobotRC/_main.ino b/Code/miniRobotRC/_main.ino index 5d1d314..cf28a5f 100644 --- a/Code/miniRobotRC/_main.ino +++ b/Code/miniRobotRC/_main.ino @@ -20,11 +20,12 @@ void setup() { void loop() { //lcdMenu(); + while(!tasten.getButtonCycle(buttonStart)) { manualDigitalDrive(); } tasten.clearButton(buttonStart); - while(!tasten.getButtonCycle(buttonStart)){ + while(!tasten.getButtonCycle(buttonStart)){ motorMapping(); } tasten.clearButton(buttonStart); @@ -32,6 +33,7 @@ void loop() { joystickSteuerung(); //TODO () } tasten.clearButton(buttonStart); + } void lcdMenu() { diff --git a/Code/miniRobotRC/fahrsteuerung_old.ino b/Code/miniRobotRC/fahrsteuerung_old.ino index 4c764b4..500a42c 100644 --- a/Code/miniRobotRC/fahrsteuerung_old.ino +++ b/Code/miniRobotRC/fahrsteuerung_old.ino @@ -1,4 +1,5 @@ void manualDigitalDrive() { + bool goOn = false; String temp_str = "T: " + String(temperature) + " Grad C"; lcdLines[5] = temp_str; @@ -48,6 +49,30 @@ void manualDigitalDrive() { radio.write(&commands, sizeof(commands)); goOn = false; } + + //Temperatur <3 + + if((millis() - temp_time) >= 5000){ // jede Sekunden + temp_time = millis(); + bool err = false; + clearCommands(); + commands[0] = getTemp; + radio.write(&commands, sizeof(commands) && !err); + long start = micros(); + radio.startListening(); + while(!radio.available()){ + //Serial.println("nix"); + if((micros()- start) >= 1){ + + err = true; + } + } + if(!err){ + radio.read(&temperature, sizeof(int16_t)); + } + radio.stopListening(); + } + // } // tasten.clearAllButtons(); } diff --git a/Code/miniRobotRC/funkInit.ino b/Code/miniRobotRC/funkInit.ino index 308995f..aa72370 100644 --- a/Code/miniRobotRC/funkInit.ino +++ b/Code/miniRobotRC/funkInit.ino @@ -1,6 +1,8 @@ void funkInit() { radio.begin(); + radio.openWritingPipe(address); + radio.openReadingPipe(0, address2); radio.setPALevel(RF24_PA_MAX); radio.stopListening(); } diff --git a/Code/miniRobotRC/miniRobotRC.ino b/Code/miniRobotRC/miniRobotRC.ino index eb73d78..322d632 100644 --- a/Code/miniRobotRC/miniRobotRC.ino +++ b/Code/miniRobotRC/miniRobotRC.ino @@ -42,6 +42,8 @@ uint16_t driveTimeout = 0; int16_t distance; int16_t temperature = 0; +int16_t temp_time = millis(); + //Funk #include #include @@ -50,5 +52,6 @@ int16_t temperature = 0; RF24 radio(A2, A3); // CE, CSN const byte address[6] = "00001"; +const byte address2[6] = "00002"; uint8_t commands[32]; From 32679f67e3cf19d792f48a25fd6e9583c5a87be1 Mon Sep 17 00:00:00 2001 From: nickg <132455a@gmail.com> Date: Sat, 8 Feb 2020 21:25:12 +0100 Subject: [PATCH 7/8] Roboter should now stop if the distance is lower than 20cm --- Code/miniRobot/miniRobot.ino | 48 ++++++++++++++++---------- Code/miniRobot/temperatureDistance.ino | 8 ++--- Code/miniRobotRC/fahrsteuerung_old.ino | 6 ++-- Code/miniRobotRC/miniRobotRC.ino | 2 +- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/Code/miniRobot/miniRobot.ino b/Code/miniRobot/miniRobot.ino index bb40118..237239d 100644 --- a/Code/miniRobot/miniRobot.ino +++ b/Code/miniRobot/miniRobot.ino @@ -13,8 +13,8 @@ RF24 radio(A0, 3); // CE, CSN byte commands[32]; //byte 0 = command long timer; -int16_t temperature; -int distance = 0; +int16_t temperature = 0; +int16_t distance = 0; void inline clearCommands() { for(uint8_t i=0; i<32; i++) { @@ -61,9 +61,6 @@ bool forwardA = true; bool forwardB = true; volatile bool driveOn = false; -int16_t temperatur = 0; - - volatile long driveTimeout = 0; volatile long driveTimeDiff = 0; @@ -79,13 +76,26 @@ void setup() { clearCommands(); //Temperatur- und Abstandsmessung + + setEchoPins(16, 6); //16: A2, 5: D5 tempDistSetup(); - setEchoPins(16, 5); //16: A2, 5: D5 timer = millis(); } void loop() { + //Temperatur- und Abstandsmessung Serial.println(temperature); + Serial.println(distance); + temperature = dallas(4, 0); + + if((unsigned long)(millis() - timer) >= 100){ + measureDistance(); + timer = millis(); + } + + distance = calculateDistance(); + + if (radio.available()) { radio.read(&commands, sizeof(commands)); commandInterpretation(); @@ -96,20 +106,21 @@ void loop() { pwmB = 0; } + + if(distance < 20){ + Serial.println("Achtung!"); + if(pwmA < 0 && pwmB < 0){ + pwmA = 0; + pwmB = 0; + } + } + + drive.setPWM_A(pwmA); drive.setPWM_B(pwmB); - //Temperatur- und Abstandsmessung - - temperature = dallas(4, 0); - - if(millis() - timer >= 100){ - measureDistance(); - timer = millis(); - } - - distance = calculateDistance(); + } void commandInterpretation() { @@ -154,8 +165,8 @@ void commandInterpretation() { driveOn = false; break; } - case getTemp : { - Serial.println("Senden!"); + case getTemp : { + Serial.println("Senden!"); radio.stopListening(); radio.write(&temperature, sizeof(int16_t)); radio.startListening(); @@ -180,5 +191,6 @@ void commandInterpretation() { } } } + clearCommands(); } diff --git a/Code/miniRobot/temperatureDistance.ino b/Code/miniRobot/temperatureDistance.ino index 216f1dd..74535f3 100644 --- a/Code/miniRobot/temperatureDistance.ino +++ b/Code/miniRobot/temperatureDistance.ino @@ -2,8 +2,8 @@ #define maxDistance 400 -int trig = 0; -int echo = 0; +int trig; +int echo; //int distance = 0; int distance2 = 0; @@ -25,8 +25,8 @@ void setEchoPins(int pin1, int pin2){ echo = pin2; } -int calculateDistance(){ - int result = distance2/ 58; +int16_t calculateDistance(){ + int16_t result = distance2/ 58; if(result > maxDistance){ result = maxDistance; diff --git a/Code/miniRobotRC/fahrsteuerung_old.ino b/Code/miniRobotRC/fahrsteuerung_old.ino index 500a42c..09b72c3 100644 --- a/Code/miniRobotRC/fahrsteuerung_old.ino +++ b/Code/miniRobotRC/fahrsteuerung_old.ino @@ -52,17 +52,17 @@ void manualDigitalDrive() { //Temperatur <3 - if((millis() - temp_time) >= 5000){ // jede Sekunden + if((unsigned long)(millis() - temp_time) >= 1000){ // jede Sekunden temp_time = millis(); bool err = false; clearCommands(); commands[0] = getTemp; radio.write(&commands, sizeof(commands) && !err); - long start = micros(); + unsigned long start = micros(); radio.startListening(); while(!radio.available()){ //Serial.println("nix"); - if((micros()- start) >= 1){ + if((unsigned long)(micros()- start) >= 1){ err = true; } diff --git a/Code/miniRobotRC/miniRobotRC.ino b/Code/miniRobotRC/miniRobotRC.ino index 322d632..e465369 100644 --- a/Code/miniRobotRC/miniRobotRC.ino +++ b/Code/miniRobotRC/miniRobotRC.ino @@ -42,7 +42,7 @@ uint16_t driveTimeout = 0; int16_t distance; int16_t temperature = 0; -int16_t temp_time = millis(); +unsigned long temp_time = millis(); //Funk #include From 48327ec5c42c4d70afa8e9c00bbf52ab2db2ca05 Mon Sep 17 00:00:00 2001 From: nickg <132455a@gmail.com> Date: Sat, 8 Feb 2020 23:15:34 +0100 Subject: [PATCH 8/8] Temperature measurement now worls more reliable. --- Code/miniRobot/miniRobot.ino | 37 +++++++++++++++----------- Code/miniRobot/temperatureDistance.ino | 23 ++++++++-------- Code/miniRobotRC/fahrsteuerung_old.ino | 15 +++++++---- Code/miniRobotRC/funkInit.ino | 2 +- Code/miniRobotRC/miniRobotRC.ino | 4 +-- 5 files changed, 47 insertions(+), 34 deletions(-) diff --git a/Code/miniRobot/miniRobot.ino b/Code/miniRobot/miniRobot.ino index 237239d..452f374 100644 --- a/Code/miniRobot/miniRobot.ino +++ b/Code/miniRobot/miniRobot.ino @@ -12,9 +12,9 @@ RF24 radio(A0, 3); // CE, CSN byte commands[32]; //byte 0 = command -long timer; +unsigned long timer; int16_t temperature = 0; -int16_t distance = 0; +uint16_t distance = 50; void inline clearCommands() { for(uint8_t i=0; i<32; i++) { @@ -70,30 +70,36 @@ void setup() { // motorB.setPWM16(2,RESOLUTION); radio.begin(); radio.openWritingPipe(address2); - radio.openReadingPipe(0, address); + radio.openReadingPipe(1, address); radio.setPALevel(RF24_PA_MAX); radio.startListening(); clearCommands(); //Temperatur- und Abstandsmessung - setEchoPins(16, 6); //16: A2, 5: D5 + setEchoPins(16, 6); //16: A2, 6: D6 tempDistSetup(); timer = millis(); } void loop() { //Temperatur- und Abstandsmessung - Serial.println(temperature); - Serial.println(distance); - temperature = dallas(4, 0); + //Serial.println(temperature); + //Serial.println(distance); - if((unsigned long)(millis() - timer) >= 100){ + + unsigned long currentMillis = millis(); + + if((unsigned long)(currentMillis - timer) >= 100){ + temperature = dallas(4, 0); measureDistance(); - timer = millis(); + distance = calculateDistance(); + Serial.println(distance); + timer = currentMillis; + } - distance = calculateDistance(); + if (radio.available()) { @@ -108,13 +114,13 @@ void loop() { if(distance < 20){ - Serial.println("Achtung!"); + //Serial.println("Achtung!"); if(pwmA < 0 && pwmB < 0){ pwmA = 0; pwmB = 0; } } - + drive.setPWM_A(pwmA); drive.setPWM_B(pwmB); @@ -166,9 +172,10 @@ void commandInterpretation() { break; } case getTemp : { - Serial.println("Senden!"); - radio.stopListening(); - radio.write(&temperature, sizeof(int16_t)); + //Serial.println("Senden!"); + radio.stopListening(); + int16_t sendData = temperature; + radio.write(&sendData, sizeof(int16_t)); radio.startListening(); break; } diff --git a/Code/miniRobot/temperatureDistance.ino b/Code/miniRobot/temperatureDistance.ino index 74535f3..a3e977c 100644 --- a/Code/miniRobot/temperatureDistance.ino +++ b/Code/miniRobot/temperatureDistance.ino @@ -5,14 +5,15 @@ int trig; int echo; -//int distance = 0; -int distance2 = 0; +uint16_t distance3 = 0; +uint16_t distance2 = 0; //ISR for PCINT20 ISR(PCINT2_vect) { - distance = pulseIn(echo, HIGH); - if(distance > 0){ - distance2 = distance; + distance3 = pulseIn(echo, HIGH); + + if(distance3 > 0){ + distance2 = distance3; } delayMicroseconds(10); @@ -26,12 +27,11 @@ void setEchoPins(int pin1, int pin2){ } int16_t calculateDistance(){ - int16_t result = distance2/ 58; - - if(result > maxDistance){ - result = maxDistance; + int16_t result2 = distance2/ 58; + if(result2 > maxDistance){ + result2 = maxDistance; } - return result; + return result2; } void measureDistance(){ @@ -89,6 +89,7 @@ void tempDistSetup(){ // Reset the trigger pin and wait a half a second digitalWrite(trig, LOW); delayMicroseconds(500); + Serial.println(echo); sei(); @@ -102,7 +103,7 @@ void runMeasurements(){ } Serial.print("Temperatur: "); - Serial.println(dallas(2, 0)); + Serial.println(dallas(4, 0)); Serial.print("Distanz: "); Serial.print(calculateDistance()); diff --git a/Code/miniRobotRC/fahrsteuerung_old.ino b/Code/miniRobotRC/fahrsteuerung_old.ino index 09b72c3..1370be8 100644 --- a/Code/miniRobotRC/fahrsteuerung_old.ino +++ b/Code/miniRobotRC/fahrsteuerung_old.ino @@ -51,26 +51,31 @@ void manualDigitalDrive() { } //Temperatur <3 - - if((unsigned long)(millis() - temp_time) >= 1000){ // jede Sekunden + unsigned long currentMillis = millis(); + if((unsigned long)(currentMillis - temp_time) >= 1000){ // jede Sekunden temp_time = millis(); bool err = false; clearCommands(); + commands[0] = getTemp; radio.write(&commands, sizeof(commands) && !err); unsigned long start = micros(); radio.startListening(); while(!radio.available()){ //Serial.println("nix"); - if((unsigned long)(micros()- start) >= 1){ - + unsigned long currentMicros = micros(); + if((unsigned long)(currentMicros - start) >= 1){ + err = true; } } if(!err){ - radio.read(&temperature, sizeof(int16_t)); + int16_t readData; + radio.read(&readData, sizeof(int16_t)); + temperature = readData; } radio.stopListening(); + clearCommands(); } // } diff --git a/Code/miniRobotRC/funkInit.ino b/Code/miniRobotRC/funkInit.ino index aa72370..fa40d29 100644 --- a/Code/miniRobotRC/funkInit.ino +++ b/Code/miniRobotRC/funkInit.ino @@ -2,7 +2,7 @@ void funkInit() { radio.begin(); radio.openWritingPipe(address); - radio.openReadingPipe(0, address2); + radio.openReadingPipe(1, address2); radio.setPALevel(RF24_PA_MAX); radio.stopListening(); } diff --git a/Code/miniRobotRC/miniRobotRC.ino b/Code/miniRobotRC/miniRobotRC.ino index e465369..f93a12c 100644 --- a/Code/miniRobotRC/miniRobotRC.ino +++ b/Code/miniRobotRC/miniRobotRC.ino @@ -39,8 +39,8 @@ bool forwardB = true; bool driveOn = false; uint16_t driveTimeout = 0; -int16_t distance; -int16_t temperature = 0; +uint8_t distance; +uint8_t temperature = 0; unsigned long temp_time = millis();