removed lib code and added .json
This commit is contained in:
parent
de67c731f6
commit
4a66883c2b
21 changed files with 2716 additions and 0 deletions
5
coderacer_mkII/.gitignore
vendored
Normal file
5
coderacer_mkII/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
67
coderacer_mkII/.travis.yml
Normal file
67
coderacer_mkII/.travis.yml
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# Continuous Integration (CI) is the practice, in software
|
||||||
|
# engineering, of merging all developer working copies with a shared mainline
|
||||||
|
# several times a day < https://docs.platformio.org/page/ci/index.html >
|
||||||
|
#
|
||||||
|
# Documentation:
|
||||||
|
#
|
||||||
|
# * Travis CI Embedded Builds with PlatformIO
|
||||||
|
# < https://docs.travis-ci.com/user/integration/platformio/ >
|
||||||
|
#
|
||||||
|
# * PlatformIO integration with Travis CI
|
||||||
|
# < https://docs.platformio.org/page/ci/travis.html >
|
||||||
|
#
|
||||||
|
# * User Guide for `platformio ci` command
|
||||||
|
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Please choose one of the following templates (proposed below) and uncomment
|
||||||
|
# it (remove "# " before each line) or use own configuration according to the
|
||||||
|
# Travis CI documentation (see above).
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Template #1: General project. Test it using existing `platformio.ini`.
|
||||||
|
#
|
||||||
|
|
||||||
|
# language: python
|
||||||
|
# python:
|
||||||
|
# - "2.7"
|
||||||
|
#
|
||||||
|
# sudo: false
|
||||||
|
# cache:
|
||||||
|
# directories:
|
||||||
|
# - "~/.platformio"
|
||||||
|
#
|
||||||
|
# install:
|
||||||
|
# - pip install -U platformio
|
||||||
|
# - platformio update
|
||||||
|
#
|
||||||
|
# script:
|
||||||
|
# - platformio run
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Template #2: The project is intended to be used as a library with examples.
|
||||||
|
#
|
||||||
|
|
||||||
|
# language: python
|
||||||
|
# python:
|
||||||
|
# - "2.7"
|
||||||
|
#
|
||||||
|
# sudo: false
|
||||||
|
# cache:
|
||||||
|
# directories:
|
||||||
|
# - "~/.platformio"
|
||||||
|
#
|
||||||
|
# env:
|
||||||
|
# - PLATFORMIO_CI_SRC=path/to/test/file.c
|
||||||
|
# - PLATFORMIO_CI_SRC=examples/file.ino
|
||||||
|
# - PLATFORMIO_CI_SRC=path/to/test/directory
|
||||||
|
#
|
||||||
|
# install:
|
||||||
|
# - pip install -U platformio
|
||||||
|
# - platformio update
|
||||||
|
#
|
||||||
|
# script:
|
||||||
|
# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
|
7
coderacer_mkII/.vscode/extensions.json
vendored
Normal file
7
coderacer_mkII/.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
"platformio.platformio-ide"
|
||||||
|
]
|
||||||
|
}
|
39
coderacer_mkII/include/README
Normal file
39
coderacer_mkII/include/README
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
This directory is intended for project header files.
|
||||||
|
|
||||||
|
A header file is a file containing C declarations and macro definitions
|
||||||
|
to be shared between several project source files. You request the use of a
|
||||||
|
header file in your project source file (C, C++, etc) located in `src` folder
|
||||||
|
by including it, with the C preprocessing directive `#include'.
|
||||||
|
|
||||||
|
```src/main.c
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Including a header file produces the same results as copying the header file
|
||||||
|
into each source file that needs it. Such copying would be time-consuming
|
||||||
|
and error-prone. With a header file, the related declarations appear
|
||||||
|
in only one place. If they need to be changed, they can be changed in one
|
||||||
|
place, and programs that include the header file will automatically use the
|
||||||
|
new version when next recompiled. The header file eliminates the labor of
|
||||||
|
finding and changing all the copies as well as the risk that a failure to
|
||||||
|
find one copy will result in inconsistencies within a program.
|
||||||
|
|
||||||
|
In C, the usual convention is to give header files names that end with `.h'.
|
||||||
|
It is most portable to use only letters, digits, dashes, and underscores in
|
||||||
|
header file names, and at most one dot.
|
||||||
|
|
||||||
|
Read more about using header files in official GCC documentation:
|
||||||
|
|
||||||
|
* Include Syntax
|
||||||
|
* Include Operation
|
||||||
|
* Once-Only Headers
|
||||||
|
* Computed Includes
|
||||||
|
|
||||||
|
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
16
coderacer_mkII/platformio.ini
Normal file
16
coderacer_mkII/platformio.ini
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:esp32dev]
|
||||||
|
platform = espressif32
|
||||||
|
board = esp32dev
|
||||||
|
framework = arduino
|
||||||
|
monitor_speed = 115200
|
||||||
|
lib_deps = itsblue/CoderacerMKII@^1.0.0
|
223
coderacer_mkII/src/CodeRacer_Example_Main.cpp
Normal file
223
coderacer_mkII/src/CodeRacer_Example_Main.cpp
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
// Example Code of a CodeRacer sketch with implementation of a webserver
|
||||||
|
#include "CodeRacer_MKII.h"
|
||||||
|
#include "Webserver.h"
|
||||||
|
|
||||||
|
CodeRacerMKII Coderacer; // Inizialization of your CodeRacer
|
||||||
|
AsyncWebServer server(80); // IMPORTANT definition of the asynchronous Web server, including port number
|
||||||
|
int Distance;
|
||||||
|
int DemoMode=0;
|
||||||
|
int maximum= 0;
|
||||||
|
int Array[160];
|
||||||
|
int Degrees[160];
|
||||||
|
int location= 0; // Some numbers we need for later...
|
||||||
|
Codeserver Test((char*)"coderacer_ap", (char*)"007coderacer"); // Creation of the webserver. enter your network's SSID and password here
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Coderacer.begin();
|
||||||
|
Coderacer.servo_sweep_left_pos=120; // Just a few adjustments to the servo_sweep parameters- that way, the servo sweeps more narrowly
|
||||||
|
Coderacer.servo_sweep_right_pos= 60;
|
||||||
|
|
||||||
|
/* One problem we came across during the testing of the Coderacer was, that the two engines don't run equally fast- meaning that even with
|
||||||
|
identical speed (let's say 130, 130), the Racer will slowly pull to one side on longer distances. To adjust this issue, all you can do for now is test
|
||||||
|
which engine is more powerful- and adjust your speed for the left and right side drives accordingly. */
|
||||||
|
Coderacer.speed_settings(140, 130);
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Test.Run(); // Calls the Run() routine, which manages everything the webserver needs to work
|
||||||
|
Coderacer.wifi_printf("Activate a switch to choose a Demonstration program.");
|
||||||
|
wait_ms(1000);
|
||||||
|
/*the IP adress of the server is given out on the Serial monitor. It is currently connected to the CodeRacer we used for testing and programming this sample code.
|
||||||
|
If the IP adress of YOUR CodeRacer differs from the one specified in Webserver.cpp, you have to change the following part of the HTML char array:
|
||||||
|
var Url ="http://192.168.1.146/"; --> var Url ="your_IP_adress"; */
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
/* the loop contains four demonstration example codes, seperated by switch/ case which are supposed to give you the idea of the
|
||||||
|
CodeRacer routines, what they do, how you can use them and what you need to consider before doing so. By turning on one of the switches, you select one of the demos.
|
||||||
|
Activate the CodeRacer by pressing the left button, and watch the CodeRacer doing (hopefully) what it is advised to. Don't hesitate to watch the Webserver as well,
|
||||||
|
instructions on how to get it running are shown and executed above. */
|
||||||
|
{
|
||||||
|
DemoMode= Coderacer.switch_check();
|
||||||
|
switch (DemoMode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
Coderacer.kitt(); // This is just some fun stuff happening while no program has been selected... feel free to edit it out :)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
/* a Demo featuring: measuring the distance, driving forward until it falls below a certain value, then driving back
|
||||||
|
for a small amount of time and turning 90 degrees to the right. NOTE: if you want to print out debug message on the Webserver,
|
||||||
|
build in a certain delay time so the AJAX protocoll can process the message (otherwise it won't get displayed). */
|
||||||
|
{
|
||||||
|
Coderacer.wifi_printf("Selected: Demo 1, activate your CodeRacer to start");
|
||||||
|
Coderacer.set_leds_all_off();
|
||||||
|
wait_ms(5000);
|
||||||
|
while(Coderacer.is_active()) // If the left button is pressed, the CodeRacer becomes active and the loop starts
|
||||||
|
{
|
||||||
|
wait_ms(300);
|
||||||
|
Distance= Coderacer.usonic_measure_single_shot_cm();
|
||||||
|
while(Distance>25)
|
||||||
|
{
|
||||||
|
Distance=Coderacer.usonic_measure_single_shot_cm();
|
||||||
|
Coderacer.servo_sweep();
|
||||||
|
Coderacer.drive_forward();
|
||||||
|
// tells the CodeRacer to drive forward while sweeping the servo from left to right (the sweeping range is defined eariler in this code) and measure the distance
|
||||||
|
}
|
||||||
|
Coderacer.stop_driving();
|
||||||
|
Coderacer.servo_set_to_center();
|
||||||
|
wait_ms(500);
|
||||||
|
Coderacer.drive_backward_for_ms(500);
|
||||||
|
wait_ms(500);
|
||||||
|
Coderacer.wifi_printf("Drehung!"); //prints out a message on the webserver
|
||||||
|
wait_ms(500);
|
||||||
|
Coderacer.turn_degree(80); // Due to the inertia of the wheels, lower the degrees of the turn a bit- in this case, although 80 are stated, the Racer does an almost perfect 90 degree turn...
|
||||||
|
wait_ms(500);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
/* a more "intelligent" way to tell the CodeRacer where to drive. Basically the idea is to let the CodeRacer drive forward until a certain distance is reached (as done before).
|
||||||
|
Then, the servo sweeps from left to right filling an array of distances, getting the index of the highest value and then turning a precise amount of degrees,
|
||||||
|
depending on that value. The scheme of the code is explained below*/
|
||||||
|
{
|
||||||
|
Coderacer.wifi_printf("Selected: Demo 2, activate your CodeRacer to start");
|
||||||
|
Coderacer.set_leds_all_off();
|
||||||
|
wait_ms(5000);
|
||||||
|
while(Coderacer.is_active())
|
||||||
|
{
|
||||||
|
Distance= Coderacer.usonic_measure_cm();
|
||||||
|
while (Distance>25) // Again a simple way to tell the Racer "drive until a distance of __ cm is reached"
|
||||||
|
{
|
||||||
|
Distance= Coderacer.usonic_measure_single_shot_cm();
|
||||||
|
Coderacer.servo_sweep();
|
||||||
|
Coderacer.drive_forward(210, 190);
|
||||||
|
}
|
||||||
|
Coderacer.stop_driving();
|
||||||
|
wait_ms(1000);
|
||||||
|
|
||||||
|
for(int i=0, k=10; i<160; i++, k++) // sweeps the servo from right to leftmost position and fills an array with the measured distances
|
||||||
|
{
|
||||||
|
Coderacer.servo_set_position_wait(k);
|
||||||
|
Array[i]=Coderacer.usonic_measure_single_shot_cm();
|
||||||
|
}
|
||||||
|
|
||||||
|
Coderacer.servo_set_to_center(); // Reset servo
|
||||||
|
wait_ms(200);
|
||||||
|
|
||||||
|
maximum= Array[0]; // Defines the maximum value of the array at the index 0
|
||||||
|
|
||||||
|
for (int c = 0; c < 160; c++) // Emitts the highest value of the distance- array. One flaw: only the first time this value shows up is saved.
|
||||||
|
{
|
||||||
|
if (Array[c] > maximum)
|
||||||
|
{
|
||||||
|
maximum = Array[c];
|
||||||
|
location = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0, k=80; i<160; i++, k--) // Finally, create an array of degrees from 80 to -80 (representing the distance array from 0 to 160)
|
||||||
|
{
|
||||||
|
Degrees[i]= k;
|
||||||
|
}
|
||||||
|
Coderacer.turn_degree(Degrees[location]); // ...And turn the servo by the number of degrees roughly representing the biggest distance!
|
||||||
|
wait_ms(500);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
/* a demo program featuring: an alternative way telling the CodeRacer to stop when a ceratin distance is reached. the Racer will drive around
|
||||||
|
happily, turning left and right until the specified value is measured. NOTE: it might occur that the Racer won't get to measure the stop distance
|
||||||
|
- if that is the case, just hold your hand in front of it so it breaks out of the while- loop ;) */
|
||||||
|
{
|
||||||
|
Coderacer.wifi_printf("Selected: Demo 3, activate your CodeRacer to start");
|
||||||
|
Coderacer.set_leds_all_off();
|
||||||
|
wait_ms(5000);
|
||||||
|
while(Coderacer.is_active())
|
||||||
|
{
|
||||||
|
Distance = Coderacer.usonic_measure_cm(); // measure the distance - at the position of the servo
|
||||||
|
Coderacer.start_stop_at_min_distance(20); // Select a distance- the CodeRacer will stop if the Usonic Sensor measures it
|
||||||
|
while(!Coderacer.stopped_at_min_distance()) // WHILE the CodeRacer hasn't stopped at the previous declared distance...
|
||||||
|
{
|
||||||
|
if(Distance > 50)
|
||||||
|
{
|
||||||
|
Coderacer.drive_forward();
|
||||||
|
Coderacer.servo_sweep();
|
||||||
|
}
|
||||||
|
else if(Distance > 40)
|
||||||
|
{
|
||||||
|
Coderacer.turn_right();
|
||||||
|
}
|
||||||
|
else if(Distance > 30)
|
||||||
|
{
|
||||||
|
Coderacer.turn_left();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Coderacer.drive_backward();
|
||||||
|
}
|
||||||
|
|
||||||
|
Distance = Coderacer.usonic_measure_cm();
|
||||||
|
// Measure the distance again- be careful with usonic_measure_cm(), as this method takes a while to complete. Calling it too fast will crash your Code.
|
||||||
|
}
|
||||||
|
Coderacer.wifi_printf("Stopped at minimal stopped distance selected by user!!");
|
||||||
|
wait_ms(2000);
|
||||||
|
Coderacer.set_inactive();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
/* a demo program showing the scheme of displaying messages in the Webserver. After doing so, take a look at the dashboard on the website!
|
||||||
|
the racer will drive a specific amounts of ticks for the left and right wheel afterwards, you can check if that works correctly looking into
|
||||||
|
the table. NOTE: you might want to disable the CodeRacer from driving away- no stopping condition built in this time, so it might
|
||||||
|
bump into something while driving... just let the wheels turn freely and watch the dashboard... */
|
||||||
|
{
|
||||||
|
Coderacer.wifi_printf("Selected: Demo 4, activate CodeRacer to start");
|
||||||
|
Coderacer.set_leds_all_off();
|
||||||
|
wait_ms(5000);
|
||||||
|
|
||||||
|
while(Coderacer.is_active())
|
||||||
|
{
|
||||||
|
Coderacer.set_obstacle_stop(true);
|
||||||
|
Coderacer.wifi_printf("Welcome...");
|
||||||
|
wait_ms(1000);
|
||||||
|
// As previously mentioned, the website resfrehes internally, but only in an interval of 750ms
|
||||||
|
// So if you want your message to be properly displayed, you got to build in a delay using wait_ms...
|
||||||
|
Coderacer.wifi_printf("Using wifi_printf");
|
||||||
|
wait_ms(1000);
|
||||||
|
Coderacer.wifi_printf("You can display custom messages on the Webserver!");
|
||||||
|
wait_ms(1000);
|
||||||
|
Coderacer.wifi_printf("But you knew that already!");
|
||||||
|
wait_ms(1000);
|
||||||
|
Coderacer.wifi_printf("Dont forget to build in small waiting windows...");
|
||||||
|
wait_ms(1000);
|
||||||
|
Coderacer.wifi_printf("So your message is transmitted properly!");
|
||||||
|
wait_ms(1000);
|
||||||
|
Coderacer.wifi_printf("Also, check out the clear button!");
|
||||||
|
wait_ms(1000);
|
||||||
|
Coderacer.wifi_printf("Now, watch the stepcounters in the table!");
|
||||||
|
wait_ms(2000);
|
||||||
|
|
||||||
|
Coderacer.drive_ticks_left(200, true);
|
||||||
|
while (true== Coderacer.is_driving()){} // IMPORTANT! halts the Code while the Racer is driving its __ steps on each side.
|
||||||
|
wait_ms(3000);
|
||||||
|
Coderacer.Reset_Stats(); // Resets the stats of the Racer, including stepcounters and speed settings to default.
|
||||||
|
Coderacer.speed_settings(255, 245); // New Speed settings for both drives...
|
||||||
|
wait_ms(3000); // The delay is once again needed so the debug message of reset_stats() is properly displayed...
|
||||||
|
Coderacer.drive_ticks_right(200, true);
|
||||||
|
while (true== Coderacer.is_driving()){}
|
||||||
|
Coderacer.wifi_printf("End of demo 3!");
|
||||||
|
wait_ms(3000);
|
||||||
|
Coderacer.set_inactive();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
250
coderacer_mkII/src/coderacer_main.cpp
Normal file
250
coderacer_mkII/src/coderacer_main.cpp
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
#include "CodeRacer_MKII.h"
|
||||||
|
|
||||||
|
#include <ESP32Servo.h>
|
||||||
|
#include "esp32-hal-ledc.h"
|
||||||
|
|
||||||
|
//----- Werte für den Ultraschallsensor -----
|
||||||
|
#define US_STOP_ABSTAND_CM 20 // Wenn der gemessene Abstand kleiner ist, hält der CodeRacer an
|
||||||
|
#define US_MIN_ABSTAND_LI_RE 8 // Wenn der Unterschied zwischen linkem und und rechtem Abstand kleiner ist, dann drehe in dieselbe Richtugn wie vorher weiter
|
||||||
|
#define MAX_ANZAHL_DREHUNGEN 10 // Wenn der Coderacer sich schon so oft gedreht hat ohne eine Stelle zu finden, wo es Platz gibt - fahren wir mal ein Stück rückwärts ...
|
||||||
|
|
||||||
|
//----- Variablen, die wir brauchen um uns Werte zu merken ----
|
||||||
|
long abstand_vorn_cm, abstand_links_cm, abstand_rechts_cm;
|
||||||
|
enum drehrichtung {links=0, rechts};
|
||||||
|
drehrichtung drehung = links;
|
||||||
|
unsigned int anzahl_drehung = 0;
|
||||||
|
CodeRacerMKII coderacer;
|
||||||
|
|
||||||
|
int aabstand[160];
|
||||||
|
void filladistance();
|
||||||
|
int adegree[160];
|
||||||
|
unsigned int ispeed=0;
|
||||||
|
float fZeit= 0;
|
||||||
|
float fSpeedminleft= 0;
|
||||||
|
float fSpeedminright=0;
|
||||||
|
float fSpeedmaxleft=0;
|
||||||
|
float fSpeedmaxright=0;
|
||||||
|
int iTicks=101;
|
||||||
|
float callibration_drive(unsigned int tickstogo, float calfactor);
|
||||||
|
|
||||||
|
unsigned int getcount_function(bool left_notright);
|
||||||
|
void set_speed_function(bool left_notright, unsigned int speed);
|
||||||
|
unsigned int get_inmin(bool left_notright);
|
||||||
|
void calculate_veliocity(unsigned int inleft, unsigned int inright, float* vleft, float* vright);
|
||||||
|
|
||||||
|
const bool LEFT = true;
|
||||||
|
const bool RIGHT = false;
|
||||||
|
const unsigned int IN_MAX = 255;
|
||||||
|
|
||||||
|
//---- Hier startet der Code zum Einstellen aller wichtigen Dinge. Setup() wird einmal ausgeführt. ----
|
||||||
|
void setup2() {
|
||||||
|
// Monitor
|
||||||
|
Serial.begin(9600); // Serial Monitor aktivieren. Mit dem Monitor kann man sich Werte und Meldungen anzeigen lassen.
|
||||||
|
|
||||||
|
// CodeRacer initialisieren
|
||||||
|
coderacer.begin();
|
||||||
|
|
||||||
|
coderacer.servo_set_to_left();
|
||||||
|
delay(10);
|
||||||
|
coderacer.servo_set_to_right();
|
||||||
|
delay(10);
|
||||||
|
coderacer.servo_set_to_center();
|
||||||
|
|
||||||
|
anzahl_drehung = 0;
|
||||||
|
drehung = links;
|
||||||
|
coderacer.set_syncstop(true);
|
||||||
|
coderacer.set_obstacle_stop(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- Hier startet unsere endlose Schleife - die immer wieder von vorn angefangen wird, wenn wir am Ende angekommen sind. Da ist unser "Fahr"Code drin, der den CodeRacer steuert
|
||||||
|
void loop2()
|
||||||
|
{
|
||||||
|
coderacer.drive_distance_mm(1000, 1000);
|
||||||
|
|
||||||
|
bool started = false;
|
||||||
|
while(coderacer.start_stop()== 1)
|
||||||
|
{
|
||||||
|
if(false == started)
|
||||||
|
{
|
||||||
|
started = true;
|
||||||
|
wait_ms(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// below - mitteln
|
||||||
|
coderacer.stop_driving();
|
||||||
|
unsigned int in_min_left = get_inmin(true);
|
||||||
|
wait_ms(1000); // do not use delay() this will create problems with interrupt routines! use the wait_ms() instead !!!!
|
||||||
|
unsigned int in_min_right = get_inmin(false);
|
||||||
|
Serial.printf("left in_min: %u right in_min: %u \n", in_min_left, in_min_right);
|
||||||
|
wait_ms(1000);
|
||||||
|
|
||||||
|
calculate_veliocity(in_min_left, in_min_right, &fSpeedminleft, &fSpeedminright);
|
||||||
|
wait_ms(1000);
|
||||||
|
calculate_veliocity(IN_MAX, IN_MAX, &fSpeedmaxleft, &fSpeedmaxright);
|
||||||
|
Serial.printf("Left vmin:%f vmax:%f Right vmin:%f vmax: %f\n", fSpeedminleft, fSpeedmaxleft, fSpeedminright, fSpeedmaxright);
|
||||||
|
//above - mitteln
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float nLeft= (fSpeedmaxleft- fSpeedminleft)/(IN_MAX- in_min_left);
|
||||||
|
float mLeft= fSpeedmaxleft-nLeft*IN_MAX;
|
||||||
|
float nRight= (fSpeedmaxright- fSpeedminright)/(IN_MAX- in_min_right);
|
||||||
|
float mRight= fSpeedmaxright-nRight*IN_MAX;
|
||||||
|
|
||||||
|
Serial.printf(" nleft: %f mleft:%f nright:%f mright:%f\n", nLeft, mLeft, nRight, mRight);
|
||||||
|
|
||||||
|
wait_ms(5000);
|
||||||
|
unsigned int vracer = 35;
|
||||||
|
unsigned int inleft = (vracer - mLeft)/nLeft;
|
||||||
|
unsigned int inright = (vracer - mRight)/nRight;
|
||||||
|
Serial.printf("inleft: %u inright:%u\n", inleft, inright);
|
||||||
|
coderacer.speed_settings(inleft, inright);
|
||||||
|
unsigned int lticks = coderacer.show_left_stepcounter();
|
||||||
|
unsigned int rticks = coderacer.show_right_stepcounter();
|
||||||
|
coderacer.drive_ticks(100,100);
|
||||||
|
while(coderacer.is_driving()){}
|
||||||
|
rticks = coderacer.show_right_stepcounter() - rticks;
|
||||||
|
lticks = coderacer.show_left_stepcounter() - lticks;
|
||||||
|
Serial.printf("Cal. Steps left: %u right: %u \n", lticks, rticks);
|
||||||
|
wait_ms(1000);
|
||||||
|
|
||||||
|
coderacer.speed_settings(inleft, inleft);
|
||||||
|
lticks = coderacer.show_left_stepcounter();
|
||||||
|
rticks = coderacer.show_right_stepcounter();
|
||||||
|
coderacer.drive_ticks(100,100);
|
||||||
|
while(coderacer.is_driving()){}
|
||||||
|
rticks = coderacer.show_right_stepcounter() - rticks;
|
||||||
|
lticks = coderacer.show_left_stepcounter() - lticks;
|
||||||
|
Serial.printf("Uncal.Steps left: %u right: %u \n", lticks, rticks);
|
||||||
|
|
||||||
|
|
||||||
|
wait_ms(1000);
|
||||||
|
coderacer.set_inactive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int get_inmin(bool left_notright )
|
||||||
|
{
|
||||||
|
unsigned int steps_before_driving = getcount_function(left_notright);
|
||||||
|
//Serial.printf("Steps before driving: %u \n", steps_before_driving );
|
||||||
|
for(unsigned int pwm_in = 0; pwm_in < 255; pwm_in = pwm_in+5)
|
||||||
|
{
|
||||||
|
unsigned int steps_after_driving = getcount_function(left_notright);
|
||||||
|
if(steps_after_driving > steps_before_driving)
|
||||||
|
{
|
||||||
|
//Serial.printf("Steps after driving: %u \n", steps_after_driving );
|
||||||
|
coderacer.stop_driving();
|
||||||
|
return pwm_in*1.1;
|
||||||
|
}
|
||||||
|
set_speed_function(left_notright, pwm_in);
|
||||||
|
wait_ms(100);
|
||||||
|
}
|
||||||
|
coderacer.stop_driving();
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int getcount_function(bool left_notright)
|
||||||
|
{
|
||||||
|
if(true == left_notright){return coderacer.show_left_stepcounter();}
|
||||||
|
else{return coderacer.show_right_stepcounter();}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_speed_function(bool left_notright, unsigned int speed)
|
||||||
|
{
|
||||||
|
if(true == left_notright){coderacer.drive_forward(speed,0);}
|
||||||
|
else{coderacer.drive_forward(0,speed);}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void calculate_veliocity(unsigned int inleft, unsigned int inright, float* vleft, float* vright)
|
||||||
|
{
|
||||||
|
coderacer.speed_settings(inleft, inright);
|
||||||
|
coderacer.set_left_start_time();
|
||||||
|
coderacer.set_right_start_time();
|
||||||
|
unsigned int iStepsbefore_left = coderacer.show_left_stepcounter();
|
||||||
|
unsigned int iStepsbefore_right = coderacer.show_right_stepcounter();
|
||||||
|
coderacer.drive_ticks(iTicks, iTicks);
|
||||||
|
while(coderacer.is_driving()){};
|
||||||
|
|
||||||
|
unsigned int iStepsafter_left = coderacer.show_left_stepcounter();
|
||||||
|
unsigned int iStepsafter_right = coderacer.show_right_stepcounter();
|
||||||
|
|
||||||
|
unsigned int iDifferenz_left = iStepsafter_left - iStepsbefore_left-1;
|
||||||
|
unsigned int iDifferenz_right = iStepsafter_right - iStepsbefore_right-1;
|
||||||
|
|
||||||
|
Serial.printf("Schritte before left: %u right: %u Steps after left:%u right:%u Steps diff left: %u right %u\n", iStepsbefore_left , iStepsbefore_right, iStepsafter_left, iStepsafter_right, iDifferenz_left, iDifferenz_right);
|
||||||
|
|
||||||
|
unsigned long lzeit_left = coderacer.show_left_time_of_last_tick()- coderacer.show_left_start_time();
|
||||||
|
unsigned long lzeit_right = coderacer.show_right_time_of_last_tick()- coderacer.show_right_start_time();
|
||||||
|
|
||||||
|
//Serial.printf("Links Startzeit:%lu Endzeit:%lu Runtime:%lu\n", coderacer.show_left_start_time(),coderacer.show_left_time_of_last_tick(), lzeit_left);
|
||||||
|
//Serial.printf("Rechts Startzeit:%lu Endzeit:%lu Runtime:%lu\n", coderacer.show_right_start_time(), coderacer.show_right_time_of_last_tick(), lzeit_right);
|
||||||
|
|
||||||
|
float fSpeedleft= iDifferenz_left/((float)lzeit_left/1000.0);
|
||||||
|
*vleft = fSpeedleft;
|
||||||
|
float fSpeedright= iDifferenz_right/((float)lzeit_right/1000.0);
|
||||||
|
*vright = fSpeedright;
|
||||||
|
//Serial.printf("Speed left: %f right: %f\n" , fSpeedleft, fSpeedright);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Serial.printf("links %i\n", coderacer.show_left_stepcounter());
|
||||||
|
//Serial.printf("rechts %i\n", coderacer.show_right_stepcounter());
|
||||||
|
//Serial.printf("%i\n", coderacer.show_distance_mm());
|
||||||
|
|
||||||
|
float callibration_drive(unsigned int tickstogo, float calfactor)
|
||||||
|
{
|
||||||
|
unsigned int stepsprevl;
|
||||||
|
unsigned int stepsprevr;
|
||||||
|
float GesamtSummeR = 0;
|
||||||
|
float GesamtSummeL=0;
|
||||||
|
unsigned int runcounter = 0;
|
||||||
|
int runs= 4;
|
||||||
|
float MittelSummeR;
|
||||||
|
float MittelSummeL;
|
||||||
|
unsigned int tickcheck= tickstogo*1.02;
|
||||||
|
for(unsigned int v= 190;v<=200;v=v+10)
|
||||||
|
{
|
||||||
|
unsigned int vr = v + calfactor*255;
|
||||||
|
unsigned int vl = v - calfactor*255;
|
||||||
|
runcounter ++;
|
||||||
|
coderacer.speed_settings(vl, vr);
|
||||||
|
Serial.println(vl);
|
||||||
|
Serial.println(vr);
|
||||||
|
int SummeR = 0;
|
||||||
|
int SummeL=0;
|
||||||
|
for (int i=1; i<=runs; i++)
|
||||||
|
{
|
||||||
|
stepsprevl = coderacer.show_left_stepcounter();
|
||||||
|
stepsprevr = coderacer.show_right_stepcounter();
|
||||||
|
coderacer.drive_ticks_left(tickstogo, true);
|
||||||
|
while (1== coderacer.is_driving()){}
|
||||||
|
delay(1000);
|
||||||
|
SummeR = SummeR + (coderacer.show_right_stepcounter() - stepsprevr);
|
||||||
|
SummeL= SummeL +(coderacer.show_left_stepcounter()- stepsprevl);
|
||||||
|
if (tickcheck<(coderacer.show_left_stepcounter() - stepsprevl))
|
||||||
|
{
|
||||||
|
Serial.printf("ERROR: calibration failed");
|
||||||
|
Serial.printf("links=%i\n" ,coderacer.show_left_stepcounter()- stepsprevl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Serial.printf("v=%i links=%i rechts=%i\n" ,v, coderacer.show_left_stepcounter()- stepsprevl, coderacer.show_right_stepcounter() - stepsprevr);
|
||||||
|
|
||||||
|
}
|
||||||
|
GesamtSummeR = GesamtSummeR+ SummeR/4.0;
|
||||||
|
GesamtSummeL = GesamtSummeL+ SummeL/4.0;
|
||||||
|
}
|
||||||
|
MittelSummeR= GesamtSummeR/(float)runcounter;
|
||||||
|
MittelSummeL= GesamtSummeL/(float)runcounter;
|
||||||
|
float CalibrationFactor= MittelSummeL/ MittelSummeR;
|
||||||
|
return CalibrationFactor;
|
||||||
|
}
|
||||||
|
|
11
coderacer_mkII/test/README
Normal file
11
coderacer_mkII/test/README
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
This directory is intended for PIO Unit Testing and project tests.
|
||||||
|
|
||||||
|
Unit Testing is a software testing method by which individual units of
|
||||||
|
source code, sets of one or more MCU program modules together with associated
|
||||||
|
control data, usage procedures, and operating procedures, are tested to
|
||||||
|
determine whether they are fit for use. Unit testing finds problems early
|
||||||
|
in the development cycle.
|
||||||
|
|
||||||
|
More information about PIO Unit Testing:
|
||||||
|
- https://docs.platformio.org/page/plus/unit-testing.html
|
5
esp32_coderacer/.gitignore
vendored
Normal file
5
esp32_coderacer/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
67
esp32_coderacer/.travis.yml
Normal file
67
esp32_coderacer/.travis.yml
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# Continuous Integration (CI) is the practice, in software
|
||||||
|
# engineering, of merging all developer working copies with a shared mainline
|
||||||
|
# several times a day < https://docs.platformio.org/page/ci/index.html >
|
||||||
|
#
|
||||||
|
# Documentation:
|
||||||
|
#
|
||||||
|
# * Travis CI Embedded Builds with PlatformIO
|
||||||
|
# < https://docs.travis-ci.com/user/integration/platformio/ >
|
||||||
|
#
|
||||||
|
# * PlatformIO integration with Travis CI
|
||||||
|
# < https://docs.platformio.org/page/ci/travis.html >
|
||||||
|
#
|
||||||
|
# * User Guide for `platformio ci` command
|
||||||
|
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Please choose one of the following templates (proposed below) and uncomment
|
||||||
|
# it (remove "# " before each line) or use own configuration according to the
|
||||||
|
# Travis CI documentation (see above).
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Template #1: General project. Test it using existing `platformio.ini`.
|
||||||
|
#
|
||||||
|
|
||||||
|
# language: python
|
||||||
|
# python:
|
||||||
|
# - "2.7"
|
||||||
|
#
|
||||||
|
# sudo: false
|
||||||
|
# cache:
|
||||||
|
# directories:
|
||||||
|
# - "~/.platformio"
|
||||||
|
#
|
||||||
|
# install:
|
||||||
|
# - pip install -U platformio
|
||||||
|
# - platformio update
|
||||||
|
#
|
||||||
|
# script:
|
||||||
|
# - platformio run
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Template #2: The project is intended to be used as a library with examples.
|
||||||
|
#
|
||||||
|
|
||||||
|
# language: python
|
||||||
|
# python:
|
||||||
|
# - "2.7"
|
||||||
|
#
|
||||||
|
# sudo: false
|
||||||
|
# cache:
|
||||||
|
# directories:
|
||||||
|
# - "~/.platformio"
|
||||||
|
#
|
||||||
|
# env:
|
||||||
|
# - PLATFORMIO_CI_SRC=path/to/test/file.c
|
||||||
|
# - PLATFORMIO_CI_SRC=examples/file.ino
|
||||||
|
# - PLATFORMIO_CI_SRC=path/to/test/directory
|
||||||
|
#
|
||||||
|
# install:
|
||||||
|
# - pip install -U platformio
|
||||||
|
# - platformio update
|
||||||
|
#
|
||||||
|
# script:
|
||||||
|
# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
|
7
esp32_coderacer/.vscode/extensions.json
vendored
Normal file
7
esp32_coderacer/.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
"platformio.platformio-ide"
|
||||||
|
]
|
||||||
|
}
|
39
esp32_coderacer/include/README
Normal file
39
esp32_coderacer/include/README
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
This directory is intended for project header files.
|
||||||
|
|
||||||
|
A header file is a file containing C declarations and macro definitions
|
||||||
|
to be shared between several project source files. You request the use of a
|
||||||
|
header file in your project source file (C, C++, etc) located in `src` folder
|
||||||
|
by including it, with the C preprocessing directive `#include'.
|
||||||
|
|
||||||
|
```src/main.c
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Including a header file produces the same results as copying the header file
|
||||||
|
into each source file that needs it. Such copying would be time-consuming
|
||||||
|
and error-prone. With a header file, the related declarations appear
|
||||||
|
in only one place. If they need to be changed, they can be changed in one
|
||||||
|
place, and programs that include the header file will automatically use the
|
||||||
|
new version when next recompiled. The header file eliminates the labor of
|
||||||
|
finding and changing all the copies as well as the risk that a failure to
|
||||||
|
find one copy will result in inconsistencies within a program.
|
||||||
|
|
||||||
|
In C, the usual convention is to give header files names that end with `.h'.
|
||||||
|
It is most portable to use only letters, digits, dashes, and underscores in
|
||||||
|
header file names, and at most one dot.
|
||||||
|
|
||||||
|
Read more about using header files in official GCC documentation:
|
||||||
|
|
||||||
|
* Include Syntax
|
||||||
|
* Include Operation
|
||||||
|
* Once-Only Headers
|
||||||
|
* Computed Includes
|
||||||
|
|
||||||
|
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
1345
esp32_coderacer/lib/CodeRacer/CodeRacer.cpp
Normal file
1345
esp32_coderacer/lib/CodeRacer/CodeRacer.cpp
Normal file
File diff suppressed because it is too large
Load diff
282
esp32_coderacer/lib/CodeRacer/CodeRacer.h
Normal file
282
esp32_coderacer/lib/CodeRacer/CodeRacer.h
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include <algorithm> // std::swap
|
||||||
|
#include <ESP32Servo.h> // Servo drive support for ESP32
|
||||||
|
#include "esp32-hal-ledc.h" // Part of ESP32 board files - Analog output
|
||||||
|
#include "BluetoothSerial.h" // Bluetooth enablement - part of ESP or standart Arduino lib
|
||||||
|
#include <vector> // support for vectors
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
|
||||||
|
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CodeRacer_H__
|
||||||
|
#define __CodeRacer_H__
|
||||||
|
|
||||||
|
//----- Fun stuff ---------
|
||||||
|
#define FUN_MIN_PAUSE_MS 120000 // minimum and maximum pause between to rounds fun
|
||||||
|
#define FUN_MAX_PAUSE_MS 300000
|
||||||
|
#define LED_SWITCH_MS 50 // speed of knight rider lights
|
||||||
|
//----- Button ------------
|
||||||
|
#define H_BUTTON_PIN 17
|
||||||
|
#define BUTTON_BOUNCING_TIME_MS 200 // bouncing delay
|
||||||
|
//----- Servo -----
|
||||||
|
#define H_SERVO_PIN 16
|
||||||
|
#define H_SERVO_LEFT_POS 145 // left position of the servo
|
||||||
|
#define H_SERVO_CENTER_LEFT 100 // left-center position of the servo
|
||||||
|
#define H_SERVO_RIGHT_POS 35 // right position of the servo
|
||||||
|
#define H_SERVO_CENTER_RIGHT 80 // right-center position of the servo
|
||||||
|
#define H_SERVO_CENTER_POS 90 // center position of the servo
|
||||||
|
#define H_SERVO_SWEEP_LEFT_POS 140 // most left sweep position of the servo
|
||||||
|
#define H_SERVO_SWEEP_RIGHT_POS 40 // most right sweep position of the servo
|
||||||
|
#define SERVO_SWEEP_TO_LEFT_STEP 5 // sweep step to the left
|
||||||
|
#define SERVO_SWEEP_TO_RIGHT_STEP -5 // sweep step to the right
|
||||||
|
#define SERVO_SWEEP_MS 10 // duration of time betwee to sweep steps
|
||||||
|
#define SERVO_MAX_POSITION 170 // maximum servo position
|
||||||
|
#define SERVO_MIN_POSITION 10 // minimum servo position
|
||||||
|
#define SERVO_SET_1TICK_POSITION_DELAY_MS 3 // minimum duration of time between two servo steps
|
||||||
|
|
||||||
|
//----- Ultrasonic sensor -----
|
||||||
|
#define H_US_TRIG_PIN 12
|
||||||
|
#define H_US_ECHO_PIN 14
|
||||||
|
#define H_US_STOP_DISTANCE_CM 25 // if the measured distance is smaller the racer maybe stopped
|
||||||
|
#define US_MAX_ECHO_TIME_US 6000 // timeout for ultrasonic sensor measurements - this is about 100cm
|
||||||
|
|
||||||
|
//----- Drives -----
|
||||||
|
#define H_DRIVE_RIGHT_SPEED 255 // default speed of right side drive. 0 ...255
|
||||||
|
#define H_DRIVE_LEFT_SPEED 255 // default speed of left side drive. 0 ...255
|
||||||
|
#define H_DRIVE_RIGHT_ENABLE_PIN 2
|
||||||
|
#define H_DRIVE_RIGHT_FWRD_PIN 4
|
||||||
|
#define H_DRIVE_RIGHT_BACK_PIN 15
|
||||||
|
#define H_DRIVE_LEFT_ENABLE_PIN 21
|
||||||
|
#define H_DRIVE_LEFT_FWRD_PIN 22
|
||||||
|
#define H_DRIVE_LEFT_BACK_PIN 23
|
||||||
|
#define H_RACER_TURN_LEFT_FOR_MS 400 // duration of time the racer will turn to left
|
||||||
|
#define H_RACER_TURN_RIGHT_FOR_MS 400 // duration of time the racer will turn to right
|
||||||
|
|
||||||
|
#define DRIVE_PWM_LEFT_CHANNEL 5 // PWM-channel for left side drive
|
||||||
|
#define DRIVE_PWM_RIGHT_CHANNEL 6 // PWM-channel for right side drive
|
||||||
|
|
||||||
|
//----- LEDs -----
|
||||||
|
#define H_LED_FRWD_PIN 26
|
||||||
|
#define H_LED_STOP_PIN 25
|
||||||
|
#define H_LED_LEFT_PIN 33
|
||||||
|
#define H_LED_RIGHT_PIN 27
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
static volatile bool coderracer_activ = false;;
|
||||||
|
static volatile unsigned long button_last_pressed_at_ms = millis();
|
||||||
|
|
||||||
|
enum ledstate {
|
||||||
|
LEDOFF,
|
||||||
|
LEDON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum drivestate {
|
||||||
|
DRIVESTOP,
|
||||||
|
DRIVEFRWD,
|
||||||
|
DRIVEBACK
|
||||||
|
};
|
||||||
|
|
||||||
|
//--- this is as preparation of the class creation
|
||||||
|
class CodeRacer {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//bluetooth
|
||||||
|
std::vector<String> _bt_ignoremsgs;
|
||||||
|
std::vector<String> _bt_onlymsgs;
|
||||||
|
bool _bluetoothcreated;
|
||||||
|
unsigned long _bt_stopOnLostConnection_timeout_ms;
|
||||||
|
unsigned long _bt_lastmessagereceived;
|
||||||
|
BluetoothSerial* _BTSerial;
|
||||||
|
|
||||||
|
//pins
|
||||||
|
uint8_t _button_pin;
|
||||||
|
uint8_t _servo_pin;
|
||||||
|
uint8_t _us_trigger_pin;
|
||||||
|
uint8_t _us_echo_pin;
|
||||||
|
uint8_t _drive_left_frwd_pin;
|
||||||
|
uint8_t _drive_left_back_pin;
|
||||||
|
uint8_t _drive_left_enable_pin;
|
||||||
|
uint8_t _drive_right_frwd_pin;
|
||||||
|
uint8_t _drive_right_back_pin;
|
||||||
|
uint8_t _drive_right_enable_pin;
|
||||||
|
uint8_t _led_frwd_pin;
|
||||||
|
uint8_t _led_stop_pin;
|
||||||
|
uint8_t _led_left_pin;
|
||||||
|
uint8_t _led_right_pin;
|
||||||
|
|
||||||
|
//servo variables
|
||||||
|
int8_t _servo_sweep_step;
|
||||||
|
uint8_t _servo_position;
|
||||||
|
unsigned long _servo_position_set_at_ms;
|
||||||
|
unsigned long _servo_position_eta_in_ms;
|
||||||
|
|
||||||
|
//drives variables
|
||||||
|
uint8_t _drive_left_speed;
|
||||||
|
uint8_t _drive_right_speed;
|
||||||
|
unsigned long _turn_left_for_ms;
|
||||||
|
unsigned long _turn_right_for_ms;
|
||||||
|
|
||||||
|
// ultrasonic variables
|
||||||
|
bool _coderacer_stopped_at_min_distance;
|
||||||
|
bool _coderacer_stop_at_distance_enabled;
|
||||||
|
unsigned long _usonic_stop_distance_cm;
|
||||||
|
unsigned long _usonic_stop_distance_us;
|
||||||
|
unsigned long _usonic_distance_us;
|
||||||
|
unsigned long _usonic_distance_cm;
|
||||||
|
|
||||||
|
//fun stuff variables
|
||||||
|
unsigned long _last_led_switched_at_ms;
|
||||||
|
uint8_t _led_count;
|
||||||
|
uint8_t _last_led_on;
|
||||||
|
unsigned long _servo_look_around_at_ms;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long _min_distance_cm;
|
||||||
|
bool _drive;
|
||||||
|
unsigned long _drive_set_at_ms;
|
||||||
|
bool _servo_sweep;
|
||||||
|
bool _coderracer_activ;
|
||||||
|
|
||||||
|
//objects
|
||||||
|
Servo* _servo;
|
||||||
|
Servo* _servo_dummy;
|
||||||
|
|
||||||
|
static void _set_button_state();
|
||||||
|
void _analog_write(uint8_t pin, uint8_t speed);
|
||||||
|
unsigned long _servo_set_position(uint8_t position);
|
||||||
|
|
||||||
|
public:
|
||||||
|
//properties
|
||||||
|
bool coderacer_fun_enabled;
|
||||||
|
|
||||||
|
uint8_t servo_center_pos; /**< The position the servo is looking straight forward. Default is 90 . Allowed are values 10<=pos<=170 */
|
||||||
|
uint8_t servo_left_pos; /**< The position the servo is looking to the left. Default is 170 . Allowed are values 10<=pos<=170 */
|
||||||
|
uint8_t servo_right_pos; /**< The position the servo is looking to the right. Default is 0 . Allowed are values 10<=pos<=170 */
|
||||||
|
uint8_t servo_sweep_left_pos; /**< When the servo is sweeping this is the left most position */
|
||||||
|
uint8_t servo_sweep_right_pos; /**< When the servo is sweeping this is the right most position */
|
||||||
|
|
||||||
|
//methods
|
||||||
|
CodeRacer();
|
||||||
|
|
||||||
|
CodeRacer(uint8_t button_pin, uint8_t servo_pin,
|
||||||
|
uint8_t us_trigger_pin, uint8_t us_echo_pin,
|
||||||
|
uint8_t drive_left_frwd_pin, uint8_t drive_left_back_pin, uint8_t drive_left_enable_pin,
|
||||||
|
uint8_t drive_right_frwd_pin, uint8_t drive_right_back_pin, uint8_t drive_right_enable_pin,
|
||||||
|
uint8_t led_frwd_pin, uint8_t led_stop_pin, uint8_t led_left_pin, uint8_t led_right_pin);
|
||||||
|
|
||||||
|
void set_inactive();
|
||||||
|
void set_active();
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
|
||||||
|
// getters
|
||||||
|
bool is_active();
|
||||||
|
bool is_driving();
|
||||||
|
bool stopped_at_min_distance();
|
||||||
|
unsigned long usonic_distance_cm();
|
||||||
|
unsigned long usonic_distance_us();
|
||||||
|
uint8_t servo_position();
|
||||||
|
unsigned long servo_position_set_at_ms();
|
||||||
|
unsigned long servo_position_eta_in_ms();
|
||||||
|
uint8_t drive_left_speed();
|
||||||
|
uint8_t drive_right_speed();
|
||||||
|
unsigned long turn_left_for_ms();
|
||||||
|
unsigned long turn_right_for_ms();
|
||||||
|
|
||||||
|
// higher level {code}racer services
|
||||||
|
void stop_driving();
|
||||||
|
void drive_forward();
|
||||||
|
void drive_forward(uint8_t left_speed, uint8_t right_speed);
|
||||||
|
void drive_backward();
|
||||||
|
void drive_backward(uint8_t left_speed, uint8_t right_speed);
|
||||||
|
void turn_left();
|
||||||
|
void turn_left(unsigned long turn_for_ms);
|
||||||
|
void turn_left(unsigned long turn_for_ms, uint8_t left_speed, uint8_t right_speed);
|
||||||
|
void turn_right();
|
||||||
|
void turn_right(unsigned long turn_for_ms);
|
||||||
|
void turn_right(unsigned long turn_for_ms, uint8_t left_speed, uint8_t right_speed);
|
||||||
|
|
||||||
|
void start_stop_at_min_distance();
|
||||||
|
void start_stop_at_min_distance(unsigned long min_distance_cm);
|
||||||
|
void stop_stop_at_min_distance();
|
||||||
|
|
||||||
|
// Bluetooth
|
||||||
|
void bt_enable_stopOnLostConnection();
|
||||||
|
void bt_enable_stopOnLostConnection(unsigned long timeout);
|
||||||
|
void bt_disable_stopOnLostConnection();
|
||||||
|
void bt_start(String name);
|
||||||
|
String bt_getString();
|
||||||
|
String bt_getString(uint8_t delimiterbyte);
|
||||||
|
bool bt_msgavailable();
|
||||||
|
void bt_addStringToIgnoreList(String stringtoignore);
|
||||||
|
void bt_clearIgnoreList();
|
||||||
|
void bt_removeStringFromIgnoreList(String stringtoignore);
|
||||||
|
|
||||||
|
// LEDs
|
||||||
|
void set_leds_left_stop_frwd_right(ledstate leftled, ledstate stopled, ledstate frwdled, ledstate rightled);
|
||||||
|
void set_leds_all(ledstate alleds);
|
||||||
|
void set_leds_all_off();
|
||||||
|
void set_leds_all_on();
|
||||||
|
|
||||||
|
// Drives
|
||||||
|
void drives_settings(uint8_t drive_left_speed, uint8_t drive_right_speed, unsigned long turn_left_ms, unsigned long turn_right_ms);
|
||||||
|
void set_drives_states_left_right(drivestate stateleft, drivestate stateright);
|
||||||
|
void set_drive_left_state(drivestate state);
|
||||||
|
void set_drive_right_state(drivestate state);
|
||||||
|
void set_drive_state(drivestate state, uint8_t frwdpin, uint8_t backpin);
|
||||||
|
void set_drives_speed_left_right(uint8_t speedleft, uint8_t speedright);
|
||||||
|
void set_drive_left_speed(uint8_t speed);
|
||||||
|
void set_drive_right_speed(uint8_t speed);
|
||||||
|
void set_drive_speed(uint8_t speed, uint8_t enablepin);
|
||||||
|
void set_drives_stop_left_right();
|
||||||
|
|
||||||
|
// Ultrasonic sensor
|
||||||
|
unsigned long usonic_measure_cm();
|
||||||
|
unsigned long usonic_measure_us();
|
||||||
|
unsigned long usonic_measure_cm(unsigned long max_echo_run_time_us);
|
||||||
|
unsigned long usonic_measure_us(unsigned long max_echo_run_time_us);
|
||||||
|
unsigned long usonic_measure_single_shot_cm();
|
||||||
|
unsigned long usonic_measure_single_shot_us();
|
||||||
|
unsigned long usonic_measure_single_shot_cm(unsigned long max_echo_run_time_us);
|
||||||
|
unsigned long usonic_measure_single_shot_us(unsigned long max_echo_run_time_us);
|
||||||
|
void usonic_set_stop_distance_cm(unsigned long stop_distance_cm);
|
||||||
|
void usonic_set_stop_distance_us(unsigned long stop_distance_us);
|
||||||
|
|
||||||
|
// Servo drive
|
||||||
|
void servo_settings(uint8_t pos_center, uint8_t pos_left, uint8_t pos_right, uint8_t sweep_left_pos, uint8_t sweep_right_pos);
|
||||||
|
uint8_t servo_set_position_wait(uint8_t position);
|
||||||
|
unsigned long servo_set_position(uint8_t position);
|
||||||
|
void servo_set_to_right();
|
||||||
|
void servo_set_to_left();
|
||||||
|
void servo_set_to_center();
|
||||||
|
void servo_sweep();
|
||||||
|
|
||||||
|
// just for fun
|
||||||
|
void kitt();
|
||||||
|
void look_around();
|
||||||
|
|
||||||
|
// previous OBSOLETE german language definitions of the methods - still needed to support MakerLab Murnau {code}racer project
|
||||||
|
// - but use the english ones for new implementations
|
||||||
|
void servo_einstellungen(uint8_t winkel_mitte, uint8_t winkel_links, uint8_t winkel_rechts, uint8_t schwenk_links, uint8_t schwenk_rechts);
|
||||||
|
void motor_einstellungen(uint8_t motor_links_tempo, uint8_t motor_rechts_tempo, unsigned long drehung_links_ms, unsigned long drehung_rechts_ms);
|
||||||
|
void anhalten();
|
||||||
|
void vorwaerts();
|
||||||
|
void rueckwaerts();
|
||||||
|
void links();
|
||||||
|
void rechts();
|
||||||
|
void servo_rechts();
|
||||||
|
void servo_links();
|
||||||
|
void servo_mitte();
|
||||||
|
unsigned long abstand_messen();
|
||||||
|
void servo_schwenk();
|
||||||
|
bool start_stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,56 @@
|
||||||
|
|
||||||
|
// Full API description of the coderacer.h can be found here: https://fenoglio.pages.itsblue.de/coderacer/
|
||||||
|
// Repository with all needed data and users guide is here: https://git.itsblue.de/Fenoglio/coderacer/tree/master
|
||||||
|
// An example for a application to control the coderacer via bluetooth can be found here: https://git.itsblue.de/Fenoglio/coderacer/tree/master/AppInventor/SimpleBTCoderacer
|
||||||
|
// - this app was developed with MIT App Inventor and can be uploaded to your account to rework it.
|
||||||
|
|
||||||
|
#include <CodeRacer.h>
|
||||||
|
|
||||||
|
CodeRacer coderacer;
|
||||||
|
String recvddata = ""; //Variable in der der Bluetooth Befehl gespeichert wird
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
coderacer.begin();
|
||||||
|
coderacer.bt_start("CodeRacer"); //Bluetooth für den Coderacer anschalten
|
||||||
|
coderacer.bt_enable_stopOnLostConnection(); //Coderacer anhalten, wenn 1 Sekunde nichts per Bluetooth empfangen wurde
|
||||||
|
coderacer.bt_addStringToIgnoreList("."); //das "." Zeichen wird beim empfangen ignoriert
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Prüfen ob Bluetooth Nachrichten angekommen sind und die gleich abholen ...
|
||||||
|
recvddata = coderacer.bt_getString(); //die Nachtricht merken (sie steht jetzt in recvdata und kann später benutzt werden)
|
||||||
|
if (recvddata != "") //wenn eine Nachricht empfangen wurde, in der was drin steht ...
|
||||||
|
{
|
||||||
|
Serial.println(recvddata);
|
||||||
|
|
||||||
|
if(recvddata == "stop")
|
||||||
|
{
|
||||||
|
coderacer.stop_driving();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(recvddata == "vor")
|
||||||
|
{
|
||||||
|
coderacer.drive_forward(255,255);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(recvddata.startsWith("rueck"))
|
||||||
|
{
|
||||||
|
coderacer.drive_backward(255,255);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(recvddata.startsWith("links"))
|
||||||
|
{
|
||||||
|
coderacer.turn_left();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(recvddata.startsWith("rechts"))
|
||||||
|
{
|
||||||
|
coderacer.turn_right();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <CodeRacer.h>
|
||||||
|
|
||||||
|
//----- settings for the ultrasonic sensor -----
|
||||||
|
#define US_STOP_ABSTAND_CM 20 // if distance goes below that - stop the racer
|
||||||
|
|
||||||
|
//----- variables we need
|
||||||
|
unsigned long distance_cm = 0;
|
||||||
|
|
||||||
|
//---- construct the coderacer object
|
||||||
|
CodeRacer coderacer;
|
||||||
|
|
||||||
|
//---- set up code - executed ones
|
||||||
|
void setup() {
|
||||||
|
// start serial monitor
|
||||||
|
Serial.begin(115200);
|
||||||
|
// initialize the coderacer
|
||||||
|
coderacer.begin();
|
||||||
|
// enable fun stuff
|
||||||
|
coderacer.coderacer_fun_enabled = true;
|
||||||
|
// look to the left, to the right and to center... :-)
|
||||||
|
coderacer.servo_set_to_left();
|
||||||
|
delay(100);
|
||||||
|
coderacer.servo_set_to_right();
|
||||||
|
delay(100);
|
||||||
|
coderacer.servo_set_to_center();
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- 'endless' loop
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
// check if the racer was started (button was toggled to coderacer active state
|
||||||
|
if(true == coderacer.start_stop()){
|
||||||
|
|
||||||
|
Serial.print("Speed of right side drive: ");
|
||||||
|
Serial.println(coderacer.drive_right_speed());
|
||||||
|
Serial.print("Speed of left side drive: ");
|
||||||
|
Serial.println(coderacer.drive_left_speed());
|
||||||
|
|
||||||
|
// measure the distance - at the position of the servo
|
||||||
|
distance_cm = coderacer.usonic_measure_cm();
|
||||||
|
|
||||||
|
coderacer.start_stop_at_min_distance(US_STOP_ABSTAND_CM);
|
||||||
|
while(!coderacer.stopped_at_min_distance()){
|
||||||
|
|
||||||
|
Serial.print("Distanc in cm: ");
|
||||||
|
Serial.println(distance_cm);
|
||||||
|
|
||||||
|
if(distance_cm > 50){
|
||||||
|
coderacer.drive_forward();
|
||||||
|
coderacer.servo_sweep();
|
||||||
|
}
|
||||||
|
else if(distance_cm > 40){
|
||||||
|
coderacer.turn_right();
|
||||||
|
}
|
||||||
|
else if(distance_cm > 30){
|
||||||
|
coderacer.turn_left();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
coderacer.drive_backward();
|
||||||
|
}
|
||||||
|
|
||||||
|
// measure the distance - at the position of the servo
|
||||||
|
distance_cm = coderacer.usonic_measure_cm();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("***** STOPPED ***** ");
|
||||||
|
Serial.print("Measured stop distanc of cm: ");
|
||||||
|
Serial.println(distance_cm);
|
||||||
|
Serial.print("Measured at servo position of: ");
|
||||||
|
Serial.println(coderacer.servo_position());
|
||||||
|
|
||||||
|
coderacer.set_inactive();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
15
esp32_coderacer/lib/CodeRacer/keywords.txt
Normal file
15
esp32_coderacer/lib/CodeRacer/keywords.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
CodeRacer KEYWORD1
|
||||||
|
begin KEYWORD2
|
||||||
|
servo_einstellungen KEYWORD2
|
||||||
|
motor_einstellungen KEYWORD2
|
||||||
|
anhalten KEYWORD2
|
||||||
|
normal_tempo KEYWORD2
|
||||||
|
vorwaerts KEYWORD2
|
||||||
|
links KEYWORD2
|
||||||
|
rechts KEYWORD2
|
||||||
|
servo_rechts KEYWORD2
|
||||||
|
servo_links KEYWORD2
|
||||||
|
servo_mitte KEYWORD2
|
||||||
|
abstand_messen KEYWORD2
|
||||||
|
servo_schwenk KEYWORD2
|
||||||
|
start_stop KEYWORD2
|
46
esp32_coderacer/lib/README
Normal file
46
esp32_coderacer/lib/README
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
This directory is intended for project specific (private) libraries.
|
||||||
|
PlatformIO will compile them to static libraries and link into executable file.
|
||||||
|
|
||||||
|
The source code of each library should be placed in a an own separate directory
|
||||||
|
("lib/your_library_name/[here are source files]").
|
||||||
|
|
||||||
|
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||||
|
|
||||||
|
|--lib
|
||||||
|
| |
|
||||||
|
| |--Bar
|
||||||
|
| | |--docs
|
||||||
|
| | |--examples
|
||||||
|
| | |--src
|
||||||
|
| | |- Bar.c
|
||||||
|
| | |- Bar.h
|
||||||
|
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||||
|
| |
|
||||||
|
| |--Foo
|
||||||
|
| | |- Foo.c
|
||||||
|
| | |- Foo.h
|
||||||
|
| |
|
||||||
|
| |- README --> THIS FILE
|
||||||
|
|
|
||||||
|
|- platformio.ini
|
||||||
|
|--src
|
||||||
|
|- main.c
|
||||||
|
|
||||||
|
and a contents of `src/main.c`:
|
||||||
|
```
|
||||||
|
#include <Foo.h>
|
||||||
|
#include <Bar.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
PlatformIO Library Dependency Finder will find automatically dependent
|
||||||
|
libraries scanning project source files.
|
||||||
|
|
||||||
|
More information about PlatformIO Library Dependency Finder
|
||||||
|
- https://docs.platformio.org/page/librarymanager/ldf.html
|
15
esp32_coderacer/platformio.ini
Normal file
15
esp32_coderacer/platformio.ini
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
;PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:esp32dev]
|
||||||
|
platform = espressif32
|
||||||
|
board = esp32dev
|
||||||
|
framework = arduino
|
||||||
|
|
128
esp32_coderacer/src/esp32_coderacer.cpp
Normal file
128
esp32_coderacer/src/esp32_coderacer.cpp
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
#include "CodeRacer.h"
|
||||||
|
|
||||||
|
#include <ESP32Servo.h>
|
||||||
|
#include "esp32-hal-ledc.h"
|
||||||
|
|
||||||
|
//----- Werte für den Ultraschallsensor -----
|
||||||
|
#define US_STOP_ABSTAND_CM 20 // Wenn der gemessene Abstand kleiner ist, hält der CodeRacer an
|
||||||
|
#define US_MIN_ABSTAND_LI_RE 8 // Wenn der Unterschied zwischen linkem und und rechtem Abstand kleiner ist, dann drehe in dieselbe Richtugn wie vorher weiter
|
||||||
|
#define MAX_ANZAHL_DREHUNGEN 10 // Wenn der Coderacer sich schon so oft gedreht hat ohne eine Stelle zu finden, wo es Platz gibt - fahren wir mal ein Stück rückwärts ...
|
||||||
|
|
||||||
|
//----- Variablen, die wir brauchen um uns Werte zu merken ----
|
||||||
|
long abstand_vorn_cm, abstand_links_cm, abstand_rechts_cm;
|
||||||
|
enum drehrichtung {links=0, rechts};
|
||||||
|
drehrichtung drehung = links;
|
||||||
|
unsigned int anzahl_drehung = 0;
|
||||||
|
CodeRacer coderacer;
|
||||||
|
|
||||||
|
//---- Hier startet der Code zum Einstellen aller wichtigen Dinge. Setup() wird einmal ausgeführt. ----
|
||||||
|
void setup() {
|
||||||
|
// Monitor
|
||||||
|
Serial.begin(115200); // Serial Monitor aktivieren. Mit dem Monitor kann man sich Werte und Meldungen anzeigen lassen.
|
||||||
|
|
||||||
|
// CodeRacer initialisieren
|
||||||
|
coderacer.begin();
|
||||||
|
|
||||||
|
coderacer.servo_links();
|
||||||
|
delay(10);
|
||||||
|
coderacer.servo_rechts();
|
||||||
|
delay(10);
|
||||||
|
coderacer.servo_mitte();
|
||||||
|
|
||||||
|
anzahl_drehung = 0;
|
||||||
|
drehung = links;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- Hier startet unsere endlose Schleife - die immer wieder von vorn angefangen wird, wenn wir am Ende angekommen sind. Da ist unser "Fahr"Code drin, der den CodeRacer steuert
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
|
||||||
|
// Abstand messen -> nach vorn ... um zu sehen, ob was passiert messen wir immer ... auch wenn der Racer nicht fahren soll
|
||||||
|
abstand_vorn_cm = coderacer.abstand_messen();
|
||||||
|
|
||||||
|
// Abfragen ob der Racer fahren soll oder nicht ...
|
||||||
|
if(true == coderacer.start_stop()){
|
||||||
|
|
||||||
|
// Abstandssensor schon verstellen ... dann hat er das bis zur nächsten Messung auch geschafft
|
||||||
|
coderacer.servo_schwenk();
|
||||||
|
|
||||||
|
// Ist die Bahn frei?
|
||||||
|
if(abstand_vorn_cm < US_STOP_ABSTAND_CM){
|
||||||
|
// Nein! Der Abstand nach vorn ist kleiner als erlaubt!
|
||||||
|
// Racer anhalten
|
||||||
|
coderacer.anhalten();
|
||||||
|
// Nach links schauen!
|
||||||
|
coderacer.servo_links();
|
||||||
|
// Abstand messen und merken.
|
||||||
|
abstand_links_cm = coderacer.abstand_messen();
|
||||||
|
// Nach rechts schauen!
|
||||||
|
coderacer.servo_rechts();
|
||||||
|
// Abstand messen und merken.
|
||||||
|
abstand_rechts_cm = coderacer.abstand_messen();
|
||||||
|
|
||||||
|
|
||||||
|
// Ist der Abstand links oder rechts groß genug genug?
|
||||||
|
// Wenn nicht - wenn der Racer sich bisher noch nicht gedreht hat - fahre ein Stück rückwarts. Wenn der Racer sich gerade schon gedreht hat, drehe in dieselbe Richtung wie vorher.
|
||||||
|
if((abstand_links_cm < US_MIN_ABSTAND_LI_RE) && (abstand_rechts_cm < US_MIN_ABSTAND_LI_RE)){
|
||||||
|
if(anzahl_drehung == 0){
|
||||||
|
coderacer.rueckwaerts();
|
||||||
|
delay(300);
|
||||||
|
coderacer.anhalten();
|
||||||
|
//noch mal Abstand messen ...
|
||||||
|
coderacer.servo_links();
|
||||||
|
// Abstand messen und merken.
|
||||||
|
abstand_links_cm = coderacer.abstand_messen();
|
||||||
|
// Nach rechts schauen!
|
||||||
|
coderacer.servo_rechts();
|
||||||
|
// Abstand messen und merken.
|
||||||
|
abstand_rechts_cm = coderacer.abstand_messen();
|
||||||
|
}
|
||||||
|
if( anzahl_drehung > MAX_ANZAHL_DREHUNGEN ){
|
||||||
|
anzahl_drehung = 0;
|
||||||
|
} else {
|
||||||
|
anzahl_drehung ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wenn der Racer sich noch nicht gedreht hat (anzahl_drehung == 0) - oder gerade rückwärts gefahren ist (anzahl_drehung == 1) drehe jetzt dahin wo mehr Platz ist;
|
||||||
|
if(anzahl_drehung <= 1){
|
||||||
|
// Welcher Abstand ist größer?
|
||||||
|
if(abstand_links_cm > abstand_rechts_cm){
|
||||||
|
// Links ist mehr Platz!
|
||||||
|
drehung = links;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// Rechts ist mehr Platz!
|
||||||
|
drehung = rechts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(drehung){
|
||||||
|
case links:
|
||||||
|
coderacer.links();
|
||||||
|
coderacer.servo_mitte();
|
||||||
|
break;
|
||||||
|
case rechts:
|
||||||
|
coderacer.links();
|
||||||
|
coderacer.servo_mitte();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// Ja! Die Bahn ist frei
|
||||||
|
// Wenn die Bahn richtig frei ist, dann können wir den Zähler fürs drehen auf 0 setzen ...
|
||||||
|
if( abstand_vorn_cm > (US_STOP_ABSTAND_CM + US_MIN_ABSTAND_LI_RE)){
|
||||||
|
anzahl_drehung = 0;
|
||||||
|
}
|
||||||
|
coderacer.vorwaerts();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
anzahl_drehung = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
11
esp32_coderacer/test/README
Normal file
11
esp32_coderacer/test/README
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
This directory is intended for PIO Unit Testing and project tests.
|
||||||
|
|
||||||
|
Unit Testing is a software testing method by which individual units of
|
||||||
|
source code, sets of one or more MCU program modules together with associated
|
||||||
|
control data, usage procedures, and operating procedures, are tested to
|
||||||
|
determine whether they are fit for use. Unit testing finds problems early
|
||||||
|
in the development cycle.
|
||||||
|
|
||||||
|
More information about PIO Unit Testing:
|
||||||
|
- https://docs.platformio.org/page/plus/unit-testing.html
|
Loading…
Reference in a new issue