Make the World a Better Place : Polite Passing and Safer Bicycling – the courteous talking bike helmet with turn signals
My wife asked if I was really going out in public with the helmet....... I did.
Then she asked if I really rode a bike in public with this helmet.......... I did.
She thinks I've totally lost my mind and have no shame.
The short video including field trials
The Polite Passing talking bicycle helmet helps improve traffic safety and promote proper greenway etiquette. People enjoy nature better and safer with polite & consistent greenway audio communication.
- While bicycling, repeating “passing on your left”grows weary after awhile, especially getting frustrated with road hogs, inattentive pedestrians, runners and bikers on the phone or listening to music.
- Bicycles are pretty quiet and can be fast. They surprise distracted people enjoying the outdoors and nature. Lets keep them safe.
- LED turn signal flashers on the rear give warning to other traffic approaching you from behind.
Version 1 – Arduino Nano control. DFPlayer audio + 3W amp + speaker, activated manually with small pushbuttons mounted in helmet.
Why version 1 ? If time permits there could be a version 2 and a version 3, .....incorporating a Nicla Sense ME using gyro signals for activation rather than pushbuttons.
The code:
#include "Arduino.h" #include "SoftwareSerial.h" #include "DFRobotDFPlayerMini.h" SoftwareSerial mySoftwareSerial(10, 11); // RX, TX DFRobotDFPlayerMini myDFPlayer; void printDetail(uint8_t type, int value); int PassLeftPB; // LOW STATE is PB is pressed int PassRightPB; // = digitalRead(3); // read the input pin, LOW STATE is PB is pressed int ApproachingBehindPB; //= digitalRead(4); // read the input pin, LOW STATE is PB is pressed int GoodDayPB; // = digitalRead(5); // read the input pin, LOW STATE is PB is pressed int MrSofteePB; // = digitalRead(6); // read the input pin, LOW STATE is PB is pressed int LeftTurnLED; int RightTurnLED; void setup() { /// add these digital inputs and outputs specific for the Polite Passing Helmet pinMode(2,INPUT_PULLUP); // Pin 2 is PASS ON LEFT PB activate on 0 pinMode(3,INPUT_PULLUP); // Pin 3 is PASS ON Right PB activate on 0 pinMode(4,INPUT_PULLUP); // Pin 4 is approaching from BEHIND PB activate on 0 pinMode(5,INPUT_PULLUP); // Pin 5 is have a good day PB activate on 0 pinMode(6,INPUT_PULLUP); // Pin 6 is the Mister Softee Ice Cream Truck Theme activate on 0 pinMode(8,OUTPUT); // Pin 8 is the Left turn signal output pinMode(9,OUTPUT); // Pin 9 is the Right turn signal output mySoftwareSerial.begin(9600); Serial.begin(115200); // Serial.println(); // Serial.println(F("DFRobot DFPlayer Mini Demo")); // Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)")); if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3. Serial.println(F("Unable to begin:")); Serial.println(F("1.Please recheck the connection!")); Serial.println(F("2.Please insert the SD card!")); while(true){ delay(0); // Code to compatible with ESP8266 watch dog. } } // Serial.println(F("DFPlayer Mini online.")); myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms //----Set volume---- myDFPlayer.volume(10); //Set volume value (0~30). myDFPlayer.volumeUp(); //Volume Up myDFPlayer.volumeDown(); //Volume Down //----Set different EQ---- myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); //----Set device we use SD as default---- myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); //----Mp3 control---- // myDFPlayer.sleep(); //sleep // myDFPlayer.reset(); //Reset the module // myDFPlayer.enableDAC(); //Enable On-chip DAC // myDFPlayer.disableDAC(); //Disable On-chip DAC // myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 //----Mp3 play commands ---- // myDFPlayer.next(); //Play next mp3 // delay(1000); // myDFPlayer.previous(); //Play previous mp3 // delay(1000); myDFPlayer.play(4); //Play GDay as a test delay(5000); // myDFPlayer.loop(1); //Loop the first mp3 // delay(1000); // myDFPlayer.pause(); //pause the mp3 // delay(1000); // myDFPlayer.start(); //start the mp3 from the pause // delay(1000); // myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255) // delay(1000); // myDFPlayer.enableLoopAll(); //loop all mp3 files. // delay(1000); // myDFPlayer.disableLoopAll(); //stop loop all mp3 files. // delay(1000); // myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535) // delay(1000); // myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535) // delay(1000); // myDFPlayer.stopAdvertise(); //stop advertise // delay(1000); // myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000) // delay(1000); // myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05. // delay(1000); // myDFPlayer.randomAll(); //Random play all the mp3. // delay(1000); // myDFPlayer.enableLoop(); //enable loop. // delay(1000); // myDFPlayer.disableLoop(); //disable loop. // delay(1000); //----Read imformation---- // Serial.println(myDFPlayer.readState()); //read mp3 state // Serial.println(myDFPlayer.readVolume()); //read current volume // Serial.println(myDFPlayer.readEQ()); //read EQ setting // Serial.println(myDFPlayer.readFileCounts()); //read all file counts in SD card // Serial.println(myDFPlayer.readCurrentFileNumber()); //read current play file number // Serial.println(myDFPlayer.readFileCountsInFolder(3)); //read file counts in folder SD:/03 } void loop() { // static unsigned long timer = millis(); // if (millis() - timer > 3000) { // timer = millis(); // myDFPlayer.next(); //Play next mp3 every 3 second. // } // if (myDFPlayer.available()) { // printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states. // } //------- my code starts here ----------------------- PassLeftPB = digitalRead(2); // read the input pin, LOW STATE is PB is pressed PassRightPB = digitalRead(3); // read the input pin, LOW STATE is PB is pressed ApproachingBehindPB = digitalRead(4); // read the input pin, LOW STATE is PB is pressed GoodDayPB = digitalRead(5); // read the input pin, LOW STATE is PB is pressed MrSofteePB = digitalRead(6); // read the input pin, LOW STATE is PB is pressed if (PassLeftPB==LOW) { for (int i=0; i<4; i++) { digitalWrite(8, HIGH); // sets the LED on delay(150); // waits for a second digitalWrite(8, LOW); // sets the LED off delay(100); // waits for a second } Serial.println(F("PASSING LEFT")); myDFPlayer.play(1); //Play left turn delay(2000); for (int i=0; i<9; i++) { digitalWrite(8, HIGH); // sets the LED on delay(150); // waits for a second digitalWrite(8, LOW); // sets the LED off delay(100); // waits for a second } } if (PassRightPB==LOW) { for (int i=0; i<4; i++) { digitalWrite(9, HIGH); // sets the LED on delay(150); // waits for a second digitalWrite(9, LOW); // sets the LED off delay(100); // waits for a second } myDFPlayer.play(2); //Play right turn delay(2000); for (int i=0; i<9; i++) { digitalWrite(9, HIGH); // sets the LED on delay(150); // waits for a second digitalWrite(9, LOW); // sets the LED off delay(100); // waits for a second } } if (ApproachingBehindPB==LOW) { myDFPlayer.play(3); //Play from behind delay(5000); } if (GoodDayPB==LOW) { myDFPlayer.play(4); //Play from behind delay(5000); } if (MrSofteePB==LOW) { myDFPlayer.play(5); //Play from behind delay(31000); } } void printDetail(uint8_t type, int value){ switch (type) { case TimeOut: Serial.println(F("Time Out!")); break; case WrongStack: Serial.println(F("Stack Wrong!")); break; case DFPlayerCardInserted: Serial.println(F("Card Inserted!")); break; case DFPlayerCardRemoved: Serial.println(F("Card Removed!")); break; case DFPlayerCardOnline: Serial.println(F("Card Online!")); break; case DFPlayerUSBInserted: Serial.println("USB Inserted!"); break; case DFPlayerUSBRemoved: Serial.println("USB Removed!"); break; case DFPlayerPlayFinished: Serial.print(F("Number:")); Serial.print(value); Serial.println(F(" Play Finished!")); break; case DFPlayerError: Serial.print(F("DFPlayerError:")); switch (value) { case Busy: Serial.println(F("Card not found")); break; case Sleeping: Serial.println(F("Sleeping")); break; case SerialWrongStack: Serial.println(F("Get Wrong Stack")); break; case CheckSumNotMatch: Serial.println(F("Check Sum Not Match")); break; case FileIndexOut: Serial.println(F("File Index Out of Bound")); break; case FileMismatch: Serial.println(F("Cannot Find File")); break; case Advertise: Serial.println(F("In Advertise")); break; default: break; } break; default: break; } }