├── .gitignore
├── opendata
├── LICENSE.md
├── README.md
├── detailnetz_ueberholvorgaenge.geo.json
└── ueberholvorgaenge.csv
└── opensensor
├── LICENSE.md
├── README.md
├── Radmesser_Schaltplan.pdf
└── radmesser
└── radmesser.ino
/.gitignore:
--------------------------------------------------------------------------------
1 | *.DS_Store
2 |
--------------------------------------------------------------------------------
/opendata/LICENSE.md:
--------------------------------------------------------------------------------
1 | ## Radmesser Open Data License
2 |
3 | Die Datensätze werden unter der Open Data Commons Attribution License (ODC-By) v1.0 zur Verfügung gestellt:
4 | https://www.opendatacommons.org/licenses/by/1.0/
5 |
6 | Bedingungen sind: Die Nennung des Ursprungsprojekts "Tagesspiegel Radmesser" und ein Link zum Originalprojekt http://radmesser.de.
7 |
8 | Die korrekte Attribution bei allen daraus entstehenden Veröffentlichungen ist also: ODC-By v1.0/Tagesspiegel Radmesser/http://radmesser.de
9 |
10 | Alternativ ist es möglich, folgendermaßen zu zitieren:
11 | ODC-By v1.0/Tagesspiegel Radmesser
12 |
13 | In English:
14 | The data published from the Tagesspiegel Radmesser Project is made available under the Open Data Commons Attribution License (ODC-By) v1.0: https://opendatacommons.org/licenses/by/index.html.
15 |
16 | This means:
17 |
18 | You are free:
19 | - To Share: To copy, distribute and use the database.
20 | - To Create: To produce works from the database.
21 | - To Adapt: To modify, transform and build upon the database.
22 |
23 | As long as you:
24 | - Attribute: You must attribute any public use of the database, or works produced from the database, in the following manner: ODC-By v1.0/Tagesspiegel Radmesser. For any use or redistribution of the database, or works produced from it, you must make clear to others the license of the database and keep intact any notices on the original database.
25 |
--------------------------------------------------------------------------------
/opendata/README.md:
--------------------------------------------------------------------------------
1 | ## Radmesser Open Data
2 |
3 | Dieser Datensatz enthält alle Überholvorgänge, die im Rahmen des Projekts “Radmesser” von 100 freiwilligen Fahrradfahrerinnen und Fahrradfahrern im Zeitraum (von 23.8.2018 bis 12.11.2018) in Berlin erfasst wurden. Zur Verfügung gestellt werden nur die Vorgänge, für die verlässliche Geo-Koordinaten vorliegen, so dass sie eindeutig einer Straße, einem Straßenabschnitt oder einem Bezirk zugeordnet werden können. Insgesamt sind das 15.561 Überholvorgänge. Den Datensatz gibt es als .geo.json und .csv.
4 |
5 | Das .geo.json ist angelehnt an den Fis-Broker Datensatz „Detailnetz“ des Berliner Senats:
6 | https://fbinter.stadt-berlin.de/fb/index.jsp
7 | Er enthält alle Detailnetz-Segmente, die von unseren Teilnehmer*innen abgefahren wurden (mit den entsprechenden Segment-Informationen). Zusätzlich zu den Senats-Informationen hat jedes Segment das Attribut „stats“, das weitere Informationen wie die einzelnen Überholabstände und die Zahl der gemessenen Überholvorgänge enthält.
8 |
9 | Das .csv enthält alle Überholvorgänge mit Abständen nach links und nach rechts, Angaben zur Tageszeit und zum Datum sowie die zugehörige Straße, die ELEM_NR des Segments, Bezirk und Straßenschlüssel gemäß dem FIS-Broker Datensatz Detailnetz.
10 |
11 |
12 | In English:
13 | This dataset contains all overtaking processes recorded by 100 voluntary cyclists in Berlin in the period from 23.8.2018 to 12.11.2018 as part of the "Radmesser" project. Only the processes for which reliable geo-coordinates are available are made available, so that they can be clearly assigned to a street, a road section or a district. This amounts to a total of 15,561 overtaking operations. The data set is available as .geo.json and .csv.
14 |
15 | The .geo.json is based on the Fis-Broker dataset "Detailnetz" of the Berlin Senate:
16 | https://fbinter.stadt-berlin.de/fb/index.jsp
17 | It contains all the "Detailnetz"-segments that have been completed by our participants (with the corresponding segment information). In addition to the Senate information, each segment has the attribute "stats", which contains additional information such as the individual overtaking distances and the number of overtakings measured.
18 |
19 | The .csv contains all overtaking operations with distances to the left and to the right, time of day and date, as well as the corresponding street, the segment ELEM_NR, district and street key according to the FIS-Broker dataset Detailnetz.
20 |
--------------------------------------------------------------------------------
/opensensor/LICENSE.md:
--------------------------------------------------------------------------------
1 |
2 | # Deutsch
3 |
4 | Copyright (c) 2019 Michael Gegg/Der Tagesspiegel Berlin
5 |
6 | Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt, sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, sie zu verwenden, zu kopieren, zu verändern, zusammenzufügen, zu veröffentlichen, zu verbreiten, und Personen, denen diese Software überlassen wird, diese Rechte zu verschaffen, unter den folgenden Bedingungen:
7 |
8 | Der obige Urheberrechtsvermerk und dieser Erlaubnisvermerk sind in allen Kopien oder Teilkopien der Software beizulegen. Außerdem muss das ursprüngliche Projekt "Tagesspiegel Radmesser" genannt werden.
9 |
10 | DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE GARANTIE BEREITGESTELLT, EINSCHLIESSLICH DER GARANTIE ZUR BENUTZUNG FÜR DEN VORGESEHENEN ODER EINEM BESTIMMTEN ZWECK SOWIE JEGLICHER RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM FALL SIND DIE AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER SONSTIGE ANSPRÜCHE HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG EINES VERTRAGES, EINES DELIKTES ODER ANDERS IM ZUSAMMENHANG MIT DER SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.
11 |
12 |
13 | # English
14 |
15 | Copyright 2019 Michael Gegg/Der Tagesspiegel Berlin
16 |
17 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
18 |
19 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software and the original Project "Tagesspiegel Radmesser" must be attributed.
20 |
21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/opensensor/README.md:
--------------------------------------------------------------------------------
1 | # Radmesser-Schaltplan und Sensorcode
2 |
3 | Dies ist der Schaltplan und der Code für den Radmesser-Sensor. Der Radmesser-Sensor wird an einem Fahrrad angebracht und kann messen, ob und in welchem Abstand das Fahrrad von einem Auto oder einem anderen Fahrzeug überholt wird.
4 |
5 | Dafür misst der Radmesser-Sensor mit zwei Ultraschallsensoren nach links. Die zwei Sensoren sind jeweils geneigt - einer nach vorne und einer nach hinten. Je nachdem, welcher Sensor das Objekt zuerst sieht, kann unterschieden werden, wer wen überholt hat. Zusätzlich misst ein weiterer Sensor den Abstand nach rechts, um zu wissen, wie viel Platz zu parkenden Autos gehalten wurde. Um die Messergebnisse zu bereinigen, muss der Abstand vom Sensor zur Außenkante des Lenkers/Fahrrads ausgemessen werden.
6 |
7 | Für eine genauere Messung empfiehlt es sich, die aktuelle Außentemperatur zu erheben, um die Temperaturabhängigkeit der Schallgeschwindigkeit zu berücksichtigen. Für eine verlässliche Messung ist zudem noch ein Foto von dem überholenden Objekt nötig. Dies kann mithilfe einer Smartphone-App aufgenommen werden.
8 |
9 | ## Elektronische Bauteile
10 | - 1x Arduino Nano (ATmega168)
11 | - 3x Ultraschallsensoren HC-SR04
12 | - 1x BLE-Modul AT-09 bzw. MLT-BT05
13 | - 1x Powerbank 2000 mAh
14 | - 1x USB A Male Pin
15 | - 1x Kippschalter
16 | - 1x LED
17 | - 1x Vorwiderstand
18 | - genügend Kabel
19 |
20 | ## Verpackung
21 | - 1x Strapubox 2004
22 | - 3x 12-20cm Kabelklettband zur Befestigung
23 | - Schrauben und Muttern zum befestigen der Klettbänder
24 |
25 | ## Erklärung
26 |
27 | Wir haben den kleinsten Arduino verwendet, hauptsächlich aus Kostengründen. Deswegen ist der Arduino-Code auf wenig Speicherverbrauch hin optimiert.
28 |
29 | Wir benutzen drei Mal die Standard-Ultraschallsensoren HC-SR04 mit Reset-Routine um die Messgenauigkeit zu erhöhen. Ausserdem schalten wir während der Messung die Arduino interrupts aus, was die Messgenauigkeit ebenfalls erhöht. ==== die Resetroutine versteht man hier nicht, würde eher generell sagen dass die dinger mit ein paar Tricks stabil genug bekommt und auf den code verweisen
30 |
31 | Die verwendeten BLE-Module waren AT-09/MLT-BT05. Gekauft haben wir sie unter dem Namen AT-09, aber der voreingestellte Name war MLT-BT05. Diese Module hatten von allen getesteten Modulen die höchste Zuverlässigkeit: Es haben alle funktioniert, die wir bestellt haben. Das Modul kann ca. alle 300 ms eine String von 18 chars senden. Um dennoch schnell genug die Daten zum Smartphone senden zu können, werden die Daten in einem auf die Anwendung hin optimierten Verfahren codiert.
32 |
33 | Die 2000 mAh Powerbank ist ausreichend für > 5 Stunden Messzeit.
34 |
35 | In das Plastikgehäuse müssen Öffnungen für die Ultraschallsensoren gebohrt/gefräst werden, damit die Ultraschallsensoren herausschauen können. Die Klettbänder wurden an dem Gehäuse verschraubt. Mithilfe von Stücken von alten Fahrradschläuchen haben wir dafür gesorgt, dass der Fahrradlack nicht von den Schraubenköpfen zerkratzt wird und der Sensor weniger hin und her schwenkt bzw. stabiler am Fahrradrohr sitzt.
36 |
37 | Die Sensoren nach links sind jeweils um ca. 10° nach vorne und nach hinten geneigt. Dieser Wert hat sich in den Tests bewährt.
38 |
39 | Um zu testen ob der Sensor funktioniert, kann eine BLE-App auf dem Smartphone installiert werden, wie z.B. die App BLE Scanner. Eine sehr detaillierte Beschreibung, wie dies funktionieren kann findet sich z.B. auf der Seite von Martyn Curry: http://www.martyncurrey.com/hm-10-bluetooth-4ble-modules/
40 |
41 | Weitere Erklärungen zur Methode und zur Datenauswertung finden sich hier: https://www.tagesspiegel.de/gesellschaft/medien/radmesser-die-genaue-methode-wie-wurden-die-ueberholabstaende-gemessen/23710682.html
42 |
43 |
44 |
45 | # Radmesser Circuit Diagram and Arduino Code
46 |
47 | This is the circuit diagram and Arduino code for the Radmesser sensor. The Radmesser sensor is supposed to be attached to a bicycle and can measure whether the bicycle is being overtaken by a car or another vehicle and at which distance.
48 |
49 | To do this, the Radmesser sensor measures to the left with two ultrasonic sensors. The two sensors are each inclined - one to the front and one to the rear. Depending on which sensor sees the object first, a distinction can be made as to who overtook whom. In addition, another sensor measures the distance to the right in order to know how much space has been held towards parked cars. To correct the measurement results, the distance from the sensor to the outer edge of the handlebar/bicycle must be measured.
50 |
51 | For a more accurate measurement, it is recommended to record the current outside temperature to take into account the temperature dependence of the speed of sound. For a reliable measurement, a photo of the overtaking object is also required. This can be done using a smartphone app.
52 |
53 | ## Electronic Parts
54 | - 1x Arduino Nano (ATmega168)
55 | - 3x ultrasonic sensors HC-SR04
56 | - 1x BLE module AT-09 bzw. MLT-BT05
57 | - 1x power bank 2000 mAh
58 | - 1x USB A Male Pin
59 | - 1x toggle switch
60 | - 1x LED
61 | - 1x dropping resistor
62 | - enough wiring
63 |
64 | ## Casing
65 | - 1x Strapubox 2004
66 | - 3x 12-20cm Velcro straps for mounting the sensor
67 | - Screws and nuts for fastening the Velcro straps
68 |
69 |
70 | ## Explanation
71 |
72 | We used the smallest Arduino, mainly for cost reasons. That's why the Arduino code is optimized for low memory usage.
73 |
74 | We use three times the standard ultrasonic sensors HC-SR04 with reset routine to increase the measurement accuracy. We also switch off the Arduino interrupts during the measurement, which also increases the measurement accuracy.
75 |
76 | The BLE modules used were AT-09/MLT-BT05. We bought them under the name AT-09 from AliExpress, but the factory default name was MLT-BT05. These modules had the highest reliability of all the modules tested: all the modules we ordered worked. The module can send a string of 18 chars every 300 ms. In order to send the data to the smartphone fast enough, the data is encoded in a procedure optimized for the application.
77 |
78 | The 2000 mAh power bank is sufficient for > 5 hours measuring time.
79 |
80 | We drilled holes in the plastic housing so that the ultrasonic sensors can look out. The Velcro tapes were screwed to the housing. With the help of pieces of old bicycle tubes, we made sure that the bicycle paint is not scratched by the screw heads and that the sensor swivels less back and forth or rather sits more stable on the bicycle tube.
81 |
82 | The sensors to the left are each tilted by approx. 10° forwards and backwards. This value has proven itself in the tests.
83 |
84 | To test whether the sensor works, a BLE app can be installed on the smartphone, such as the BLE Scanner app. A very detailed description of how this works can be found on the Martyn Curry website: http://www.martyncurrey.com/hm-10-bluetooth-4ble-modules/
85 |
86 | Further explanations of the method and data evaluation can be found here (German language): https://www.tagesspiegel.de/gesellschaft/medien/radmesser-die-genaue-methode-wie-wurden-die-ueberholabstaende-gemessen/23710682.html
87 |
--------------------------------------------------------------------------------
/opensensor/Radmesser_Schaltplan.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tagesspiegel/radmesser/ba3548e3f3e449cb9b6d2afa1bd86dd05922b93e/opensensor/Radmesser_Schaltplan.pdf
--------------------------------------------------------------------------------
/opensensor/radmesser/radmesser.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * Radmesser Sensor Arduino Code:
3 | *
4 | * Author: Michael Gegg
5 | * EMail: michael.gegg@tagesspiegel.de
6 | *
7 | * Description:
8 | * This is the code for the Arduino in the Radmesser-Sensor setup. The Arduino
9 | * used in the Radmesser experiment was the Arduino Nano ATmega168. This
10 | * produces memory limitations. If the ATmega328 is used the code can be
11 | * written in a more human friendly manner.
12 | *
13 | */
14 |
15 | // library for the BLE module communication
16 | // this fixes the pins for the BLE module to D9 -> RX and D8 -> TX
17 | #include
18 | AltSoftSerial BTserial;
19 |
20 | // pins for the ultrasonic sensors:
21 | // sensor 1 measures to the left/back, sensor 2 measures to the left/front,
22 | // sensor 3 measures to the right
23 | const short TRIGGER_PIN3 = 4;
24 | const short ECHO_PIN3 = 5;
25 |
26 | const short TRIGGER_PIN2 = 6;
27 | const short ECHO_PIN2 = 7;
28 |
29 | const short TRIGGER_PIN1 = 10;
30 | const short ECHO_PIN1 = 11;
31 |
32 | // left threshold (in units of 10 microseconds)
33 | // If a left facing sensor measures something closer than this, the measurement
34 | // is discarded. This prevents anything closer than the edge of the handlebar
35 | // to trigger an event.
36 | short left_threshold = 0;
37 |
38 | // ultrasonic response time in microseconds
39 | short duration = 0;
40 |
41 | // time since the start of the measurement (in units of 200 milliseconds)
42 | unsigned long tmeasure = 0;
43 |
44 | // storage for a single char that comes form the BLE module, which
45 | // was sent by the smartphone
46 | char swap = ' ';
47 |
48 | // buffer for input received from the BLE module
49 | String input = "";
50 |
51 | // `ret` encodes the measurements, and is sent via the BLE Module:
52 | //
53 | // The AT-09 sends a string of 20 characters, where the last two characters
54 | // are reserved for the new line character. This leaves 18 characters for data
55 | // encoding. The AT-09 can send roughly every 300 milliseconds.
56 | // If the strings are transferred to the AT-09 faster than that for a short
57 | // while, the data just arrives a bit delayed. If the transfer rate is too fast
58 | // for an extended period, data will be lost.
59 | //
60 | // 18 characters every 300 milliseconds is not much. We still used this
61 | // BLE-Module since it was the most stable and reliable one that we tested,
62 | // and since it is quite cheap.
63 | // Due to this restriction in data transfer rate we encoded all data as 8bit
64 | // characters.
65 | //
66 | // The first character is used for the arduino time, which is a bit off, since
67 | // we are using noInterrupts(). The unit is 200 milliseconds, so that the time
68 | // overflows after 256*200 milliseconds, which can be corrected on the app side.
69 | //
70 | // The remaining 17 characters are reserved for the distance measurement. 8
71 | // measurements each for the two left sensors and one measurement for the right
72 | // sensor. The sensors time out after 24 milliseconds. If all sensors time out
73 | // this means that the string is filled in >400 milliseconds. If objects like
74 | // cars come close, this rate will increase, since the sound travel time is
75 | // less. If there is an object within one meter left and right, this time drops
76 | // to ~100 milliseconds. Overtaking events are usually short, so this does not
77 | // produce problems in most cases. There is the possibility to apply a distance
78 | // dependent delay between measurements, but this has the drawback that
79 | // sometimes short and close overtaking events cannot be recorded properly.
80 |
81 | String ret = "000000000000000000";
82 |
83 | // tstart is the arduino time (millis()) of the start of the measurement
84 | unsigned int tstart = 0;
85 |
86 | // index for the ret string
87 | unsigned short i = 0;
88 |
89 | // if true the measurement is enabled, if false the measurement is disabled
90 | bool flag = false;
91 |
92 | // write the time to the first character of the ret string
93 | // units are 200 milliseconds since measurement start
94 | void writeTime() {
95 | tmeasure = millis() - tstart;
96 | tmeasure /= 200;
97 | swap = tmeasure % 256;
98 | ret.setCharAt(0,swap);
99 | }
100 |
101 | // Convert the measured time of the HC-SR04 to a single character:
102 | // Takes the time for a ONEWAY travel between object and sensor in units
103 | // of 10 microseconds. Due to the timeout, this number is < 1200,
104 | // (which corresponds to roughly 4m distance to the object at around 4°C.)
105 | // We divide this number by 4.7 (1200 / 256 ~ 4.69) to encode the distance
106 | // with 47 microsecond (~1.5 cm) resolution, which is more than enough.
107 | char convertChar(const short &deltat) {
108 | return deltat / 4.7;
109 | }
110 |
111 | // Measurement function:
112 | // returns the time that the sound wave took ONEWAY between the object and the
113 | // sensor, otherwise returns the timout constant.
114 | // The units are 10 microseconds.
115 | // The noInterrupts() is very important for accuracy, without this the measured
116 | // distances are off by many centimeters.
117 | // Resets the HC-SR04 if it timeouts. This step reduces the notorious noise of
118 | // the cheap HC-SR04 sensors.
119 | void measure(const short &trigger,const short &echo) {
120 | delayMicroseconds(5);
121 |
122 | // trigger
123 | noInterrupts();
124 | digitalWrite(trigger, HIGH);
125 | delayMicroseconds(10);
126 | digitalWrite(trigger, LOW);
127 |
128 | // reads the echoPin, returns the sound wave travel time in microseconds
129 | // timeout in microseconds corresponds to roughly 4m distance to the object at
130 | // roughly 4°C, if its warmer the distance gets bigger
131 | duration = pulseIn(echo, HIGH, 24000);
132 | interrupts();
133 |
134 | // pulseIn will only return 0 if it timed out.
135 | // therefore we reset the HC-SR04 to increase measurment accuracy
136 | if (duration == 0) { // if the measurment timed out
137 | pinMode(echo, OUTPUT); // then we set echo pin to output mode
138 | digitalWrite(echo, LOW); // we send a LOW pulse to the echo pin
139 | delayMicroseconds(200);
140 | pinMode(echo, INPUT); // and finally we come back to input mode
141 | }
142 |
143 | if (duration) duration /= 20;
144 | else duration = 1200;
145 | }
146 |
147 | // initialize serial for monitoring
148 | void setupSerial() {
149 | Serial.begin(9600);
150 | Serial.print("Sketch: "); Serial.println(__FILE__);
151 | Serial.print("Uploaded: "); Serial.println(__DATE__);
152 | }
153 |
154 | // initialize the HC-SR04
155 | void setupUltrasonic(short trigger,short echo, short no) {
156 | // initialize pins for HC-SR04
157 | pinMode(trigger, OUTPUT);
158 | pinMode(echo, INPUT);
159 | // reset the trigger pin and wait a half a second
160 | digitalWrite(trigger, LOW);
161 | delayMicroseconds(500);
162 | // initial test measurement
163 | measure(trigger,echo);
164 | Serial.print("Initial test measurement Sensor ");
165 | Serial.print(no);
166 | Serial.print(": ");
167 | Serial.print(duration);
168 | }
169 |
170 | // check response of the BLE module
171 | void checkResponse() {
172 | delay(600);
173 | while (BTserial.available()) {
174 | swap = BTserial.read();
175 | Serial.print(swap);
176 | }
177 | Serial.println("");
178 | }
179 |
180 | // setup the BLE module:
181 | // This step needs to be changed if a different BLE module is used.
182 | void setupBLE() {
183 | // intitialize serial connection to AT-09
184 | BTserial.begin(9600);
185 | Serial.println("BTserial started at 9600");
186 | delay(500);
187 | BTserial.println("AT+DEFAULT");
188 | checkResponse();
189 | BTserial.println("AT+ROLE0");
190 | checkResponse();
191 | BTserial.println("AT+TYPE0");
192 | checkResponse();
193 | BTserial.println("AT+NAMEradmesser");
194 | checkResponse();
195 | BTserial.println("AT+RESET");
196 | checkResponse();
197 | }
198 |
199 |
200 | // setup functon
201 | void setup() {
202 | setupSerial();
203 | setupUltrasonic(TRIGGER_PIN1,ECHO_PIN1,1);
204 | setupUltrasonic(TRIGGER_PIN2,ECHO_PIN2,2);
205 | setupUltrasonic(TRIGGER_PIN3,ECHO_PIN3,3);
206 | setupBLE();
207 | }
208 |
209 |
210 | // Main function
211 | void loop() {
212 | // Check for notifications from the connected device, e.g. disable and enable
213 | // measurment commands 's' and 'm'
214 | while(BTserial.available()) {
215 | swap = BTserial.read();
216 | input.concat(swap);
217 | delay(10);
218 | }
219 |
220 | if( input != "" || swap != ' ' ) {
221 | Serial.print("data received");
222 | Serial.println(input);
223 |
224 | // Decide what to do:
225 | // 'dxy': The measurement is started if the sensor receives a string
226 | // starting with d and the time xy that the sound travels
227 | // from the sensor to the outer edge of the handlebar, in units of
228 | // 10 microseconds, encoded as a number with usually two digits
229 | // e.g. d47 for 470 microseconds ~ 15cm
230 | // 'm': The measurement can also be started by sending the 'm' character
231 | // 's': The measurement can be stopped by sending the 's' character,
232 | // this step sometimes needs to be done multiple times, if the
233 | // character is sent during the measurement
234 | // 'r': The arduino can be reset by sending the 'r' character
235 | //
236 | // Anything else also stops the measurement
237 | if (input.charAt(0) == 'd') {
238 |
239 | Serial.println("inner distance:");
240 | input.remove(0,1);
241 | left_threshold = input.toInt();
242 |
243 | // set the measurement flag to true
244 | flag = true;
245 |
246 | // set the start time of the measurement
247 | tstart = millis();
248 |
249 | Serial.print(left_threshold);
250 | } else if (swap == 'm') { // enable the measurement
251 | Serial.println("enabled");
252 | flag = true;
253 | } else if (swap == 's') { // disable the measurement
254 | Serial.println("disabled");
255 | flag = false;
256 | } else if (swap == 'r') { // restart the arduino
257 | Serial.println("received r");
258 | asm volatile (" jmp 0");
259 | } else {
260 | // set the measurement flag to false if something weird happened
261 | flag = false;
262 | }
263 | input = "";
264 | swap = ' ';
265 | }
266 |
267 | if (flag) {
268 | // This is the measurement cycle:
269 | // First the time is written, then four pairs of measurments to the left are
270 | // recorded, then a single measurement to the right and then another four
271 | // measurements to the left. Then the date is sent via the BLE Module, which
272 | // needs a small delay of 20 milliseconds to properly work.
273 | //
274 | // The measurement to the right is placed in the middle so that the
275 | // measurement to the left has two breaks of ~20-25 milliseconds instead of
276 | // one break of ~40-50 milliseconds. This setup performed better, produced
277 | // less errors due to left side measurement interrupts.
278 | //
279 | writeTime(); // write current time to first char in ret
280 | i = 0; // index in ret
281 |
282 | while(i<4) { // write four pairs of measurements to the string
283 |
284 | // back sensor
285 | measure(TRIGGER_PIN1,ECHO_PIN1);
286 | if (duration > left_threshold) { // only if it was 'outside' the bicycle
287 | Serial.print("Sensor 1: ");
288 | Serial.println(duration);
289 | ret.setCharAt(1+2*i,convertChar(duration));
290 |
291 | //front sensor
292 | measure(TRIGGER_PIN2,ECHO_PIN2);
293 | if (duration > left_threshold) {// only if it was 'outside' the bicycle
294 | Serial.print("Sensor 2: ");
295 | Serial.println(duration);
296 | ret.setCharAt(1+2*i+1,convertChar(duration));
297 | i++;
298 | }
299 | }
300 | }
301 |
302 | // one measurement to the right
303 | measure(TRIGGER_PIN3,ECHO_PIN3);
304 | ret.setCharAt(17,convertChar(duration));
305 |
306 | while (i<8) { // write another four pairs of measurements to the string
307 |
308 | // back sensor
309 | measure(TRIGGER_PIN1,ECHO_PIN1);
310 | if (duration > left_threshold) { // only if it was 'outside' the bicycle
311 | Serial.print("Sensor 1: ");
312 | Serial.println(duration);
313 | ret.setCharAt(1+2*i,convertChar(duration));
314 |
315 | // front sensor
316 | measure(TRIGGER_PIN2,ECHO_PIN2);
317 | if (duration > left_threshold) { // only if it was 'outside' the bicycle
318 | Serial.print("Sensor 2: ");
319 | Serial.println(duration);
320 | ret.setCharAt(1+2*i+1,convertChar(duration));
321 | i++;
322 | }
323 | }
324 | }
325 |
326 | // send the information
327 | BTserial.print(ret);
328 | Serial.println(ret);
329 | delay(20); // delay neccessary for BLE Module
330 | swap = ' ';
331 | }
332 | }
333 |
--------------------------------------------------------------------------------