element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Better World with Arduino
  • Challenges & Projects
  • Project14
  • Better World with Arduino
  • More
  • Cancel
Better World with Arduino
Blog Polite Passing and Safer Bicycling – the talking bike helmet with turn signals ** Version 1 **
  • Blog
  • Forum
  • Documents
  • Events
  • Leaderboard
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Better World with Arduino to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: robogary
  • Date Created: 23 Apr 2022 1:37 AM Date Created
  • Views 12472 views
  • Likes 12 likes
  • Comments 9 comments
  • better world with Arduino
  • arduino
  • betterworldch
Related
Recommended

Polite Passing and Safer Bicycling – the talking bike helmet with turn signals ** Version 1 **

robogary
robogary
23 Apr 2022

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  

https://youtu.be/sLN3rrYaoKE

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

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.  

imageimageimageimage

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. 

imageimageimageimage

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;
}

}

  • Sign in to reply
Parents
  • vishwasn
    vishwasn over 3 years ago

    Awesome build. I had made something similar using arduino promini and neopixel LEDs ( Just to have Chase mode with minimal wires). 

    You don't have permission to edit metadata of this video.
    Edit media
    x
    image
    Upload Preview
    image
    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • robogary
    robogary over 3 years ago in reply to vishwasn

    thats a nice build too.   WS2812s can let you do just about anything.

    I'm working on a BLE version right now to use the Nicla sensor mounted on the helmet to provide head gesture feedbacks to an Arduino Nano 33 Sense mounted on the handlebars. The Nicla will significantly lighten the weight of stuff on the helmet.

    My BLE learning curve is really steep tho. The lingo is taking some time to nail down as well. Loading the example codes in Arduino IDE proves the BLE hardware is working but the examples arent helpful to build a project from.  I wish for a max case code mode where the Nicla "advertises" all it's "services" and "characteristics" and the Arduino Sense can read them all.  From there unneeded code can be commented or deleted. I hope to have something by the cutoff date. 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • vishwasn
    vishwasn over 3 years ago in reply to robogary

    Yeah, that application can resolve a lot of issues and reduce the total weight and size of the project. In mine, I have housed an ADXL345+Arduino Pro mini+ 250mAh battery+TP4056 charger inside that black box behind. I would suggest you find an optimal point where the head motion is significant to get the change in the sensor value. Otherwise, Nicla Sense ME supports Edge.ML by KTH. You can try that and make an ML Model which will reduce your burden. Here's an article by ralphjy/products/arduino/b/blog/posts/nicla-sense-me-machine-learning-using-edge-ml

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • vishwasn
    vishwasn over 3 years ago in reply to robogary

    Yeah, that application can resolve a lot of issues and reduce the total weight and size of the project. In mine, I have housed an ADXL345+Arduino Pro mini+ 250mAh battery+TP4056 charger inside that black box behind. I would suggest you find an optimal point where the head motion is significant to get the change in the sensor value. Otherwise, Nicla Sense ME supports Edge.ML by KTH. You can try that and make an ML Model which will reduce your burden. Here's an article by ralphjy/products/arduino/b/blog/posts/nicla-sense-me-machine-learning-using-edge-ml

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube