Go Down

Topic: Sonic Eye For The Blind (Read 25981 times) previous topic - next topic


I the spirit of the Holiday I post this subject for the community if all of us can join hand to make  people's life just a little easier- I hope.

Part: Arduino + HC-SR04 + 400ohm resistor + 2N3904 Transistor and a earphone/headphone.

-D6,D7,D8 are the pin of the Arduino, Trig and Echo are the pin of the Transducer and final Base, Emitter, Collector are the pin of the transistor-

- Trig ->D6 

- Echo->D7

- D8 to -/\/\/\/\/\/\- Base

- Emitter -> Ground.

- Earphone legs are connected to Colletor & 5v

Of course all other Ground & 5V as normal.

If you want to hear the result and copy the code please get into Facebook/eyefortheblind

- The giving season is coming up- I ordered enough part for 100 units. And they are coming (Mostly from China).

Each include:
ATmega328P-PU, Transducer, DC booster to power the unit by battery, transistor,  female 1/8 audio jack.

I am willing to give away for those who want to make A Christmas gift for his/hers. And I only ask you to paid the postage fee to the Church or any other Charity organization.

Merry Christmas & Happy New Year (a little early???)


Can you please post a copy of your sketch, using code tags.

Please use code tags.. See section 7 http://forum.arduino.cc/index.php/topic,148850.0.html

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

Tom.... :)
Everything runs on smoke, let the smoke out, it stops running....


Let me draw my sketch I post it later


Here is the quick draw. Please See attached!

I hope it's OK

Peace & Love



And here is the code



Code: [Select]

/* I use sleep for delay to save batter */
#include <avr/sleep.h>
#include <avr/wdt.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#define echoPin 7 // Echo Pin
#define trigPin 6 // Trigger Pin
#define LEDPin 13 // Onboard LED

#define to_note ((Pulsemax-Pulsemin)/(sizeof(notes)/2))
#define to_note_div (((Pulsemax-Pulsemin)/(sizeof(notes)/2))/6)
char f_wdt=0;
/*************** THe frequency of the piano notes from HI to LOW */
unsigned int notes[]={4978,4699,4435,4186,3951,3729,3520,3322,3136,2960,2794,2637,2489,2349,2217,2093,1976,1865,1760,1661,1568,1480,1397,1319,1245,1175,1109,1047,988,
int maximumRange = 430; // Maximum range needed in centimeter
int minimumRange = 4; // Minimum range needed
long Pulsemax = 25026;  //430*58.2 how much time need for 430 cm
long Pulsemin =233;      // 4*58.2
//int to_note,to_note_6;
long duration; // Duration used to calculate distance
void setupUltra();

void setup_WDT(){

  // CPU Sleep Modes
  // SM2 SM1 SM0 Sleep Mode
  // 0    0  0 Idle
  // 0    0  1 ADC Noise Reduction
  // 0    1  0 Power-down
  // 0    1  1 Power-save
  // 1    0  0 Reserved
  // 1    0  1 Reserved
  // 1    1  0 Standby(1)

  cbi( SMCR,SE );      // sleep enable, power down mode
  cbi( SMCR,SM0 );     // power down mode
  sbi( SMCR,SM1 );     // power down mode
  cbi( SMCR,SM2 );     // power down mode

//  setup_watchdog(4); // 1/2 second

void system_sleep() {

  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here

  sleep_mode();                        // System sleeps here

    sleep_disable();                     // System continues execution here when watchdog timed out
    sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON


// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
//  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
//  ww=bb;
//  Serial.println(ww);

  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag

void setupUltra() {
// Serial.begin (9600);
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
 digitalWrite(LEDPin, LOW);
// to_note=(Pulsemax-Pulsemin)/(sizeof(notes)/2); //
// to_note_6=to_note/6;

void setup() {
  // iterate over the notes of the melody:
  int x;
//  Serial.begin(9600); 


#define full_note 80
//#define haft_note 80
void loop() {
  // no need to repeat the melody.
  /* The following trigPin/echoPin cycle is used to determine the
 distance of the nearest object by bouncing soundwaves off of it. */
 int thedelay;
 long theitem_rem,theitem;
 digitalWrite(trigPin, LOW);

 digitalWrite(trigPin, HIGH);
 digitalWrite(trigPin, LOW);

 duration = pulseIn(echoPin, HIGH,Pulsemax+Pulsemin);// a little more than the furthest point


// distance = duration/58.2;

if( duration<Pulsemax && duration>Pulsemin )
//     Serial.println(theitem);
       {tone(8, notes[theitem],full_note); delay(full_note);}
          case 0:tone(8, notes[theitem],full_note); delay(full_note);
          case 1:
          case 2:
                tone(8, notes[theitem]-duration,full_note); delay(full_note);
          case 3:
          case 4:
                tone(8, notes[theitem]-duration,full_note); delay(full_note);
          default:  tone(8, notes[theitem+1],full_note); delay(full_note);
       if(theitem>=24)thedelay=4; //256ms NORMAL
             {// this is for the case somthing nearer  up front about 1m
               setup_watchdog(2); //1/2 second
         if(theitem>=16)thedelay=3; //256ms NORMAL
          else if(theitem>=12)
              {// SUCH A THE CHAIR FRONT
              setup_watchdog(1); //1/2 second
              thedelay=2; //256ms}
       else if(theitem>=7)//ARM Length
           {//within arm length
//           setup_watchdog(1); //1/2 second
//           system_sleep();
           thedelay=2; //256ms
          else // verr very close
            thedelay=1;//128ms Very close about to hit
//           setup_watchdog(theitem);
         //system_sleep();// 128 ms second
   else thedelay=4;
   if(theitem>(sizeof(notes)/2)-1) thedelay=5;
   setup_watchdog(thedelay); //1/2 second



In regard to the ultrasonic transducer it has an MCU EM78P153S.

With The schematic;

I like to reprogram it.

I hope you can help me to manage the "Threshold" and the "signal" pins (int the receiver part)-




The flaw design of the HC-SR04

It drains the power The design should use P60/INT pin as he 'TRIG' function to enable the unit to got to sleep mode to save the power; The users need  in this application need it.

To solve the problem the MCU need  reprogrammed.

If any of you can help me to locate a "not so expensive" programer for the ELAN EM78P153HS?


How to program the "OPTION REGISTER" using ICP as described in this


In this case I thin I can reprogram the whole HC-SR04 as a self contain unit without any other add-on.




See this article for a more or less complete rebuild of the HC-SR04. Only the analog circuitry is retained, and that is improved. http://uglyduck.ath.cx/ep/archive/2014/01/Making_a_better_HC_SR04_Echo_Locator.html


Dec 10, 2014, 07:22 pm Last Edit: Dec 10, 2014, 11:24 pm by P-Tran
See this article for a more or less complete rebuild of the HC-SR04. Only the analog circuitry is retained, and that is improved. http://uglyduck.ath.cx/ep/archive/2014/01/Making_a_better_HC_SR04_Echo_Locator.html
The design is only capable to recognize the object of a few centimeters away much less than 1" or 2". Beyond that it just stops with randomized signals.

If anyone want to use Atmega328 (Arduino Uno) to reprogram the signals then:
(1) Lift the power pin of the Chinese MCU.
(2) Branch its pins to your Arduino. (See the attachment) BUT----BUT---BUT


The 'Threshold' signal needs to be coupled to  output between 2.4->2.5V.  (Tested and it's OK)
(Serially place a 40->45K between your Arduino pin and the actual 'Threshold'- I have not tested this YET--Edited: This scheme -----Failed.)

(3) You may need to branch one or two leg(s) of the TRANSMITTER to the speakers/head phone. Optional via a triac to eliminate the "click" happened when it emits the ultrasonic wave.

(4) To save energy - Making the 9V battery last for weeks. Then you only power the Vcc of the HC-SR04 by one OUTPUT pin of the Atmega and when it's needed.-- Less than 3 milliseconds per use.


Dec 10, 2014, 07:56 pm Last Edit: Dec 10, 2014, 10:14 pm by P-Tran
Here is the code to process the signal:

temp_var1 & temp_var2 are initially set in order to accommodate to various MIPS setting of unit , Ex: Arduino Uno is 16MIPS.

It's so sensitive to recognize object with less than 1 centimeter away - Though it's not the interest of the project.

--It provides the samples[] with the value at the "tic" number when the 'Signal' pin change it sign.

For Arduino Uno 16mhz each "tic' represents 1/2 microseconds

For those want to use internal clock of the Atmega328 then each 'tic" represents 1 microsecond.

-- temp_var1 is the how many value it puts on the samples array.

-- Sometime I use JMP and other time RJMP, it is for the timiing to be exact.

//D3 is the signal pin

Code: [Select]

#define MY_COUNTER (0x3C) 
// this is for 16Mhz clock
// For 8Mhz Clock then #define MY_COUNTER ((0x3C)*2) 
//GLOBAL Variables:
unsigned int samples[64], temp_var2,temp_var1;

temp_var2=MY_COUNTER ;


 asm volatile (
  "ldi      r30, lo8(samples)    \n\t"
  "ldi      r31, hi8(samples)    \n\t"
  "clr      r6                   \n\t"

  "LDI      R19, 0               \n\t"

  "LDI      R18, 128              \n\t"
  "ADD      R18, r30             \n\t"
  "LDS      r16, (temp_var2)     \n\t"
  "MOV      r10,r16              \n\t"
  "LDS      r20, (temp_var1)     \n\t"

  "SBIC      0x09,3      \n\t"
  "jmp      startSet    \n\t"
  //*****************************************************DONE SET UP*******************************
  "startClr:             \n\t"

  "add       r6,r20       \n\t" //1    1        // do not use INC it does not set the Carried Flag
  "ADC       r16,r19      \n\t" //1    1   
  "BREQ      done         \n\t" //1    1   
  "NOP                    \n\t" //1    1   
  "SBIS      0x09,3      \n\t" //  1   2 
  "jmp       startClr    \n\t" //  3
//*******************************  8 
  "add       r6,r20       \n\t" //     1        // do not use INC it does not set the Carried Flag
  "ADC       r16,r19      \n\t" //     1   
  "BREQ      done         \n\t" //     1   

  "ST      Z+, r6        \n\t"//       1
  "SUB     r16,r10       \n\t"//       1
  "ST      Z+, r16       \n\t"//       1
  "ADD     r16,r10       \n\t"//       1 
  "CPSE    r30,r18       \n\t" //      1  compare skip if equal read nor than 64 times
  "rjmp    startSet      \n\t" //      2   branch if T is set
//**********************************  16   
  "rjmp    done           \n\t"
  "startSet:              \n\t" // branch if T is set
  "ADD       r6,r20       \n\t" //1    1   
  "ADC       r16,r19      \n\t" //1    1   
  "BREQ      done         \n\t" //1    1   
  "NOP                    \n\t" //1    1   

  "SBIC      0x09,3      \n\t" // 1    2
  "jmp       startSet    \n\t" // 3 
  "add       r6,r20      \n\t" //      1        // do not use INC it does not set the Carried Flag
  "ADC       r16,r19     \n\t" //      1   
  "BREQ      done        \n\t" //      1   
  "ST      Z+, r6        \n\t"   //    1   
  "SUB     r16,r10       \n\t"   //    1   
  "ST      Z+, r16       \n\t"   //    1   
  "ADD     r16,r10       \n\t"   //    1   

  "CPSE   r30,r18       \n\t" //       1        compare skip if equal reak nor than 32 times
  "rjmp    startClr    \n\t" //        2         branch if T is set
  "jmp    done          \n\t" //              branch if T is set
  "done:                             \n\t"   
//  "done3:                             \n\t"   
//  "STS     (k6),r6             \n\t"
//  "STS     (k16),r16           \n\t"
//  "STS     (k18),r18           \n\t" 
//  "STS     (k20),r20           \n\t"
//  "STS     (k30),r30           \n\t"
//  "STS     (k10),r10           \n\t"
//  "STS     (k31),r31           \n\t"   
  "ldi      r24, lo8(samples)        \n\t"
//"STS     (k24),r24           \n\t"        //for debug
  "SUB      r30,r24                  \n\t"
  "LSR      r30                      \n\t" // divide by 2
  "STS     (temp_var1),r30           \n\t"   



You don't need to use the above ASM code.

It is for those who want to do mores such as Doppler effect . . . .

pulseIn(SIGNAL_PIN, LOW, . . .); also works well, very well !!!!



Are any of these still available as I am building a similar project and this could be useful for guidance?



Hi, I'm trying to do a version of this project but, I've got a little bit of a problem , I've wired my arduino up and the LED is emitting light, and the audio jack is emitting sound at the same time, in a sequence, but I don't think the HC-SR04 sensor's doing anything and it's just completing the circuit. The aim is to have the audio jack and the LED on when things are near the sensor, and off when they're out of the sensors way. Can somebody help?


Can somebody help?
Can somebody post code, schematic and debug prints?
Does somebody have an oscilloscope?
"Pete, it's a fool (who) looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.


Strange. I actually built this device before the first post and I'm just reading it now. I toiled for days. LOL

Go Up