Colecago's Blog » Microprocessor, Project, Tech

Robot Luggage- My Ben Heck Experience

Back in November I won a hat from Ben Heck, the host of the Ben Heck show produced by Newark Element14 http://www.newark.com/ and http://canada.newark.com/

I went and picked the hat up in person and talked to him and his assistant Alyson, they were finishing up the latest episode of the Ben Heck show.  See here for more info

http://blog.colecago.com/?p=38

 

During the visit, it was brought up that I might be able to help on a future episode.  Well that day came February 4th.  The project was robot luggage.  We started out by brainstorming over Skype.  I had thought about this prior and this is what we decided on:

2 Ultrasonic sensors (receivers) on the luggage, 1 Ultrasonic sensor (transmitter) on the person (the target), 1 Wireless transmitter/receiver on each.  The wireless is used to initiate the remote ultrasonic ping on the target.  I thought this was the better route than using wireless RSSI on the transceivers for a few reasons;

–  We don’t know what frequencies are in use in an airport and don’t want to be interfered with

– Wireless bounces a lot and is strange sometimes how it is affected by humidity, near ground effects, etc

–  If not using RSSI and instead using Time of Flight, you’d need a very fast micro to record the distance, Ultrasonic sound travels much slower and its easier to discern a distance

 

I went to the shop the next day to do the recording.  It was a little bit weird being on camera as you can tell I didn’t do the best acting in the beginning.  It became easier and more comfortable later on.  The recording day was all rehashing the design for the camera.  We went over why we chose what parts, the mechanical design of the device, dimensional analysis for the speed and many other things.  It was about 4 hours of work for 8 minutes of video.

 

Our next recording date was several weeks later as we needed to get the parts in.  That day consisted of more of the mechanical work and testing out all the electrical components.  Ben made a preliminary wheel, we soldered wires to all of our electronics and mounted them and added batteries.  I had a lot of trouble working with the motor drives because everything needed to be sent in hex and it’s hard to find a good terminal program in windows7 that lets you do that, had I brought a windows xp computer, I could have used realterm, which is my go to terminal.  I ended up using XCTU which is digi’s terminal program, originally meant to configure the xbee chips.  It was not supported on win7 but it worked.

Also, a note on UART dyslexia, if you are designing anything with a UART interface, please, please, mark your terminals in some manner like TXOut, RXIn so we know what direction the traffic should be.  Most things are marked TX and RX but they don’t indicate if its the TX of that device or the one connecting to it, I’ve seen it both ways on modules that use UART. Here is the best quote I’ve seen on this

Before purchasing this part you need to know if you have a condition called UART dyslexia. This is a neurological disorder that will render you incapable of properly wireing this device no matter how my times you triple check the the wiring. I have this disorder and I have only found three possible solutions:
1) Find someone else without UART dyslexia to wire it up for you
2) When you get the board, immediatly scratch out the silk screen for the TX and RX pins. You will have a better chance attaching the wires at random than attemping to determine the proper connections in your screwed up head. Test the device and if it doesn’t work swap the lines. The advantage of this approach is that you didn’t spend hours trying to figure out the wrong way to wire the connections.
3) Try to figure out the proper connections and do the opposite of what you think is correct. I have had some success with this approach. -MotiveForce sparkfun comment

I got some wheels spinning and we got the wireless generically working, and that was about it for the day.  One big comment about the transistor inverter-

Originally I wanted to do a NPN inverter but I wanted the signal pulled low so it was always low if the input was floating, this required me to change to the pnp approach, I switched the arrow, but did not switch the pins of the device.  Emitter should have went to VCC and collector to the signal out/pulldown resistor.  That is why it did not work.  The arrow represents the internal diode (because of PN junctions) of the device and you can think of it as the direction the current will flow, so of course current cannot flow backwards through it and the device didn’t work.  That was a fundamental mistake on my part, not much to blame it on but nerves and working on the fly on camera.

I was supposed to come up the next Saturday and Sunday, but I got pretty sick, so I sat alone in my lab all day Saturday working on code

Let me say this, I hate programming for Arduino.  It’s a great platform for hobbyists and gets people into electronics and programming.  There are a ton of boards out there and quite the following.  Most Arduinos are based on AVRs which I use all the time at work.  I figured I’d do it as an Arduino this time, and I did not enjoy it.  This is how I expected the program to work

Decide to take a reading, send out a serial wireless command to do a ping, count on a uS timer until both left and right ping received, the distance is the turn value

I couldn’t find uS timers, so I tried the next approach

Decide to take a reading, send out a serial wireless command to do a ping, do pulsein to record time for one receiver, repeat for second receiver

This didn’t work as the serial library is so bloated that variable lag was causing my values to be off 50-150uS whereas the difference values I was looking for many times were less than that. I hooked up a scope and the end point of the value was bouncing but not the difference, it must be from inconsistent serial lag to the remote sensor. Basically I had to read them both on the same wireless ping to get accurate results.

Use interrupts, I set both ping sensors on an interrupt so when they changed state, I’d check the second sensor to see if it triggered, detatch the interrupt so it doesn’t happen again before I’m ready and then when I receive the next interrupt that is my distance.

Well, that didn’t work either, I think either the arduino doesn’t like detaching an interrupt within that interrupt or just how long it takes to do a digital read (which I didn’t know yet) was causing grief.

Next try, sit in a loop that’s doing uS delays and counting up (with a timeout) and polling the pins to see when they change (because they received the ping back), then receive that, set some flags so you know which one went first and wait for the second one, then do the difference value etc.

This didn’t work either, I think because digital read takes a very long time (longer than it should). Once I changed it to read directly from the port (PINB & 0xyadayada) that approach worked.

The whole project I was struggling with arduino based problems, if I had better access to the lower level parts of the AVR, especially timing interrupts, I would have been fine. Once I got the error values working correctly, the project worked great. Next time I skip the arduino and go avr studio and straight c.  Once I got the terminal result below, I went to bed

 

Error: -26
Direction: Left
Error Sum: -262
Error Correction -9.12

Error: -17
Direction: Left
Error Sum: -490
Error Correction -9.15

Error: -13
Direction: Left
Error Sum: -503
Error Correction -8.28

Error: -10
Direction: Left
Error Sum: -513
Error Correction -7.63

Error: -2
Direction: Left
Error Sum: -558
Error Correction -6.08

Error: 1
Direction: Right
Error Sum: 1
Error Correction 0.26

Error: 5
Direction: Right
Error Sum: 10
Error Correction 1.35

Error: 9
Direction: Right
Error Sum: 19
Error Correction 2.44

Error: 18
Direction: Right
Error Sum: 90
Error Correction 5.40

Error: 23
Direction: Right
Error Sum: 113
Error Correction 6.88

Error: 28
Direction: Right
Error Sum: 141
Error Correction 8.41

I was moving the target from left to right in front of the receivers, Error was the difference between the left and right times, Direction was which direction to turn, Error sum is basically the integral term before weighting, correction was what to add to the turn value.

The next day I showed up with my own box of kleenex, hand sanitizer, and trash bag as to not infect Ben and we went to work.  We got everything installed, Ben finished the 3rd leg and handle and I changed the code so it would send the turn value to the motor controllers.  Off the bat, it worked pretty well, had to do tweaking but I was surprised at how well it worked increasing and decreasing the separate wheel speeds based on location of the target.  I added a distance timeout for too close and too far, tweaked the P and I weights, and added flashing lights for status.  We tried a smaller battery pack but it died pretty short into it so we went back to the huge lead-acid batteries.  We got it following well and then I left.  Ben and Alyson finished closing up the front, added some decoration, and finished the taping.  All and all, it was an awesome experience, I had followed Ben’s work on HaD and it was a once in a lifetime experience to work with him, I hope I get to work with him more in the future.

Watch the full video below

 

 

Here is a little bit longer explanation of the program flow

Functions:
Setup()
Loop()
doPingDiff()
setToZero()
updateDrives()

Powerup
Setup-
Set up the 3 serial ports
Serial is for debug at 9600
Serial1 is for motor control at 38400 and 2 stop bits!
Serial2 is for zigbee for remote ping
Set up leds
Send some commands to motor control

Main
Loop-
Clear out important variables like difference and distance
See if handle switch is in disabled position
Flash status LED
If Not Disabled;        Do 4 pings and average difference result and distance result
If too close to person (based on distance); disable
If Difference looks good and not disabled; update the drives and
clear timeout; else increase timeout
If timeout counter is too high, disable
If disabled; set the drives to zero and blink lights

doPingDiff-
Do the high low thing to start both receivers
Send Zigbee start command
Wait for either left or right sensor to go to zero or timeout; record
that setpoint
Wait for second sensor to go to zero or timeout; record that setpoint
and break loop
Calculate the difference by subtracting
Calculate the distance by adding both values and dividing by 10 (for
scaling speed)
Return the difference (which is our error)

updateDrives-
Calculate the direction of the error (basically left or right turn)
If direction has changed, clear out the error sum (integral part of PI Loop)
Add Error to the Error Sum
Calculate turn value by doing Kp*error + Ki*errorSum where Kp and Ki
are set to 0.5 and 0.25 respectively and then add to 128 which is our
Zero
Calculate the speed by taking our above distance divided by two, then
subtract from 128 because forward is 0-128 (with 0 being max allowed)
Make sure turn isn’t greater than 250 or less than 5 (preventing
overflow or underflow)
Make sure speed isn’t less than 5 (preventing an underflow)
If Debug is set output all of these numbers through the Serial port as well

setToZero-
Set speed and turn to 128 (bidirectional data around 128, 0 is max
one way 255 is max other way

I’ve also attached the code for download.  I’ts a .c file, but is actually the .ino, wordpress doesn’t like .ino files so just rename it to something.ino

Robot C Code

 

I don’t have the dimensions of the luggage, but here is a build list of the electronics:

Motors and controller- http://www.robotshop.com/drive-system-12-volt.html

Microprocessor board (brains)- http://www.sparkfun.com/products/10744

Ultrasonic Sensors (x3)- http://www.parallax.com/tabid/768/ProductID/92/Default.aspx

Wireless Boards (x2) – http://www.sparkfun.com/products/10414

Power Convertor – Don’t remember, it was some off the shelf Buck Switch Mode powersupply with 5V output

63 thoughts on “Robot Luggage- My Ben Heck Experience

  1. Good Day,
    Thank you so much for posting this project, I’m working on a similar system that works with the same concept. I’m fixing up a golf cart to follow me around the golf course. I have all the electronics(motor controller, batteries, ping sensors, xbee’s and arduino) ready to go. I’m having one hurtle I was hoping you could shed some light on. I’ve tried using some of your code you posted but I’m a little confused with the serial1 and serial2, are these strictly for motor control and xbee trigger? and if so how do I use just the serial2 for the xbee trigger? I’ve tried compiling the code and get this error I’ve pasted below.

    [ Robo_luggage.ino: In function 'void setup()':
    Robo_luggage:74: error: 'Serial1' was not declared in this scope
    Robo_luggage:75: error: 'Serial2' was not declared in this scope
    Robo_luggage.ino: In function 'long int doPingDiff()':
    Robo_luggage:182: error: 'Serial2' was not declared in this scope
    Robo_luggage:212: error: 'PINE' was not declared in this scope
    Robo_luggage:216: error: 'PINE' was not declared in this scope
    Robo_luggage.ino: In function 'void setToZero()':
    Robo_luggage:234: error: 'Serial1' was not declared in this scope
    Robo_luggage.ino: In function 'void updateDrives(long int, long int)':
    Robo_luggage:272: error: 'Serial1' was not declared in this scope]

    Could you please shed some light on this and maybe explain what I might be able to do to get the code to compile as well as use the serial2 function?

    Thank you in advance for your time and considertion
    Dave Pina

    • My guess is that you aren’t using the same Arduino. We used the Mega Pro 3.3V. It had 3-4 serial ports and a IO’s on PORTE. Serial was the computer port (for debugging and programming), Serial1 was the motor control board and Serial2 was the Zigbee.

    • Hi Dave,

      Your project sounds interesting to me. I am retired now, though I was major in digital electronics. Yet 30 years in management distant me from toying with them. I would love to put this pet project into my garage.

      If you were successful into getting this done, can you shoot me your parts list, and schematics?

      Really appreciated.

      • Ben’s show is more about proof of concepts, never full production ready ideas. We did make this and it worked pretty well. If I would do it again I’d probably go completely wireless, I was worried about interference and such but I think it would be less of an issue than I thought.

        No schematics, it was a short time build and we don’t really make schematics for the show. A partial parts list is at the bottom of the post.

        • Thank you for your reply. What do you mean by “go with completely wireless”? Which technology will you implement? Also my question is if there are two such luggage next to each other, how will the robot know which one to follow? Perhaps that’s the other reason that you were thinking of changing the hand shaking technology?

          • Currently the luggage sends out a wireless signal to tell the target to start an ultrasonic ping, then it listens for pings and figures out which ear received it first to determine a left or right correction, also because it initiated the ping it knows approximately the distance away. In the future I might build one with 3 antennas and maybe use RSSI to track, I’m not sure how well that will work though. I could do time of flight but that would require a much faster control loop because the radio waves propagate much faster than sound.

            Right now there is no way for it to discern one target from another, it just follows the ultrasonic signal. This was a proof of concept for Ben’s show only and never meant to turn into a real product.

  2. Hi there,
    I would like to get further explanation from you on how to make the 2 ping sensors communicate with each other. For now, we managed to transmit pulses from one ping sensor (A) but the other ping sensor (B) isn’t able to receive the pulses from sensor (A). Hope to get a reply from you soon. Thank you.

    • You need to enable them around the same time. Basically I sent a wireless signal telling Sensor A to start its Ping, then I toggled the line for Sensor B to start it’s ping and made sure that the Ping Sensor B saw was the Ping from Sensor A. They both need their sensor lines toggled around the same time to begin the Ping sequence.

      • Hi, thanks for the reply. From your explanation, that means ping sensor A and ping sensor B are sending out pulses at the same time pulsing each other? Or can I make it in such a way that Ping sensor A is programmed just to transmit and ping sensor B is programmed just to receive pulses from ping sensor B? Thank you.

        • You can start the PING process, but I don’t think you can stop them from sending and receiving without removing their sending and receiving cones. That’s the good part about the PING sensors, they have definitive send and receive pieces so you can remove send on the receiver and receive on the sender, though the receive on the sender isn’t really a big deal. Also it might not matter much to remove the sender on the receiver, because the first PING it receives back are likely from the target and not its own reflected PINGS, meaning it will ignore its own returning PINGs in favor of the first responses it gets from the target.

  3. Hi, I intend to built a luggage robot for a higher weight (up to 50 kg). What components (motor, motor control etc.) would you suggest for this application?

    • Not really sure, maybe look into electric wheelchair motors? As for control, you might be able to use the controller on board with those, otherwise look for motor drives, hopefully with encoder feedback, that can handle the load of those motors.

  4. Good Day!!
    You folks gave me some great info. a few months ago and since then I’ve been working on a robo caddy that can follow me around the golf course. So far so good, how ever there is one obstacle I need to over come. This is the drive motors, I understand you used motors with feedback encoder. I assume the encoder on the drive motors is required in order to work properly. I’m implementing much larger motors to drive the robo caddy around the golf course. Would it be wise to use an encoder with these larger motors or can the code work without an encoder? I’m currently using a Sabertooth 2×25 motor driver that communicates via serial or PWM. Is it possible to use this motor driver without an encoder or am I chasing the impossible?

    Thank you again for your time!!
    Dave Pina

    • The PI loop is created with the dual drive motors in mind. If you were going to go encoderless you run the risk of not actually knowing how fast your drive tires are and drifting left or right or not being able to steer properly. If you had to go encoderless you are probably better off losing tank-like two drive wheel system and do something more like a separate drive system and steer system (like traditional vehicles use).

  5. Hello,
    I am trying to build a robot follower with the sensing part based on the idea you guys were doing here. I have a question about removing the emitter cones on the Ping attached to the robot. How did you do it? Did you just simply cut the cones out of the sensor?
    Thank you,

  6. hello^^
    im korean, can i request to you difficult one thing
    at first i should say to you sorry
    i am a student in south korea
    i go to university also i have so many classes
    but one of them is to make wheelcheir that can follow a service dog
    so i wanna know how could you make this luggage
    so could i see your programming source?
    i will never use for anything except for my class
    thank you

  7. hi… im currently doing my undergrad. design,, pertaining to human following cart,. i just want to know the connection of your xbee to arduino and the connection of xbee in the transmitter side..

    can u send me the schematic diagram of your circuit???

    tnx in advance..

    • I don’t have a schematic sorry. Zigbee transmitter was powered from 3.3V and just the Tx of the Arduino was tied to the input of the Zigbee. On the receiver side the Zigbee was again powered from 3.3V and the output line was put through an inverter before going to the Ping sensor.

  8. tnx so much for the reply sir.. is the schematic of the inverter,, above is correct? then wat kind of transistor did you use for the inverter??

    and one more thing that i just want to confirm is,… did you used arduino on the transmitter side? i mean,, the ping sensor that will put to the user??

    may i ask to you to provide me just a sketch on how did you connect the xbee to the pin of the ping sensor?

  9. pls… give me some light sir on the connection… i need to finish may design this coming march,,, and your project is the one that i used for the guide on building my prototype…

    i really need your help sir…..

    your information that you will give to me will be appreciated…

  10. thank you very much for the quick responce sir… i will visit now the site yoy gave,,, and i’ll come back here if there something need to confirm to you… thanks again sir… :)

  11. hi sir,, im here again,,, i just wanna ask if what is the configuration of xbee..? did you configure it using XCTU software?? sorry im juzt a newbie in xbee…

  12. gud day sir,, is there any way to communicate the ultrasonic reciever and transmitter with out using xbee?

    there is a xbee here in my country but but the price is too expensive..

    can i use the circuit of ultrasonic beacon instead?

    • Yeah looking back on it, I could have done it better in a few ways. In the end all that matters is the difference in times, so you could set up the target to just auto beacon and then listen with the other two and just use the difference between them. In the end that’s all I ended up using, I just knew when to start listening because I initiated the sequence with the wireless. You will have to work out sync issues, and the pings timeout after a bit, but it can be done without any wireless at all. Heck you could time them by just turning them on at the same time or maybe an output on the robot you plug into to tell the target to start and then they just stay in sync after that. Lots of possibilities.

  13. sir,, what if i use another arduino board on the transmitter side the program the ping sensor to initialize or trigger if there is an ultrasonic sound recieve from the reciever side? is it possible? what do you think sir?

    • Yeah, its like I was saying. One side, the target we’ll call it, just sends out pings at regular intervals. You can do this with an Arduino on that side, or you could use a 555 timer. On the robot you still have the 2 ears and an Arduino to decode the times between interrupts. The only problem you’ll run into is syncing up, the pings have a time out period, so maybe you get clever with the start up routines on both ends to get into sync.

  14. Great job!I am planning to doing this for my final year project.
    But i have a question here,i dun want to use the handle as a switch,(a lot of mechanical work to complete that handle)so what can i use?

  15. I would like to do this project with much lower level skill. I just want to make a model of what a real one might look like. Therefore, I am using cheaper parts such as simple DC motors and off brand Ping sensors(4 pin with an echo and trig). I am also trying to make the code very simple. My setup is 2 Ping sensors, 2 motors, and an Arduino on the luggage part and 1 Ping sensor with an Arduino on what the human would wear.
    My Luggage Code:

    const int motorPin1 = 9;
    const int motorPin2 = 10;
    const int echoPin1 = 11;
    const int echoPin2 = 12;

    void setup(){
    pinMode(motorPin1, OUTPUT);
    pinMode(motorPin2, OUTPUT);
    pinMode(echoPin1, INPUT);
    pinMode(echoPin2, INPUT);
    }

    void loop(){

    long duration1, duration2, cm1, cm2;

    duration1 = pulseIn(echoPin1, HIGH);
    duration2 = pulseIn(echoPin2, HIGH);

    cm1 = microsecondsToCentimeters(duration1);
    cm2 = microsecondsToCentimeters(duration2);

    if (cm1 < cm2)
    {
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, HIGH);
    }

    if (cm2 < cm1)
    {
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin1, HIGH);
    }

    if (cm1 == cm2)
    {
    digitalWrite(motorPin1, HIGH);
    digitalWrite(motorPin2, HIGH);
    }

    delay(100);
    }

    long microsecondsToCentimeters(long microseconds)
    {
    return microseconds / 29;
    }
    My Transmitter Code:

    const int trigPin = 12;

    void setup(){
    pinMode(trigPin, OUTPUT);
    }

    void loop(){
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(trigPin, LOW);
    delay(100);
    }
    As you can see they are very simple and since I do not have all the parts yet, I just want to know if my code will work. Thanks in advance!

    • I don’t think this will work well for a few reasons, you aren’t synced with your transmitter and using PulseIN which is a blocking command, thus the ear for distance2 won’t be heard until distance1 is finished, thus sometimes distance2 will be the difference between distance1 and distance2 and sometimes it will be the echo of a second ping if it was ignored because it happened during distance1. That’s why I couldn’t use those in my code, I did try them. You an go with can unsynced transmitter, but you will have to be listening to both ears at the same time like I did.

      Also, you aren’t using any analog control, basically you are full on or full off with your motors, so you go ahead full speed forward, if one distance is greater you stop and go full on with one motor but not the other until they are equal. When you get code that gives you good distances, the motor control will basically make your robot oscillate back and forth pretty heavily. I would do some type of PWM motor control, so analogwrite instead of digitalwrite. Your turn values are way too aggressive, I would do some scaling based off of how different the left and right ears are similar to what I did.

      Good Luck!

      • So to fix the first problem you mentioned, what can I use instead of pulseIn. I looked through your code but could not find the solution.

        To fix the second problem, you suggest that I do softer turns such as analogWrite(motorPin1, 255) analogWrite(motorPin2, 150) for example to not be so abrupt. Also, you say to only make it turn if there is a major difference between the 2 sensors. How would I go about doing this.

        By the way, I am very impressed that you still help people months after the Ben heck episode. Thank you so much!

        • If you look through my code at pingdiff that basically finds the difference between them by listening to both of them, here is the pseudo code

          doPingDiff-
          Do the high low thing to start both receivers
          Send Zigbee start command
          Wait for either left or right sensor to go to zero or timeout; record
          that setpoint
          Wait for second sensor to go to zero or timeout; record that setpoint
          and break loop
          Calculate the difference by subtracting
          Calculate the distance by adding both values and dividing by 10 (for
          scaling speed)
          Return the difference (which is our error)

          Not sure how well this will work with your setup, but its worth a try.

          You can either use a set turn value like you said with 255 and 150, play with the values for stability, or you can base it off of the difference. Like analogwrite(255-difference/5) type of thing.

          Also, make sure to use a transistor on the output of the arduino, don’t run the motor directly from it. I recommend a MOSFET with a pulldown resistor, also make sure to use a flyback diode, a setup like this
          http://www.nerdkits.com/videos/motors_and_microcontrollers_101/

          Or use this kit like I used on the glue gun episode (I did the hardware and software for that)
          https://www.sparkfun.com/products/315

          Still use your pull-down resistors on the control lines.

          • I am using the transistors, diodes, and resistors for both motors so that is taken care of.

            In your actual code under doPingDiff you have:
            pinMode(pingPin1, OUTPUT);
            pinMode(pingPin2, OUTPUT);
            digitalWrite(pingPin1, LOW);
            digitalWrite(pingPin2, LOW);
            delayMicroseconds(2);
            digitalWrite(pingPin1, HIGH);
            digitalWrite(pingPin2, HIGH);
            delayMicroseconds(5);
            digitalWrite(pingPin1, LOW);
            digitalWrite(pingPin2, LOW);
            Isn’t this the code used to send out a Ping? I do not understand the use of this because the actual luggage does not transmit at all. Once you set the Pings back as in INPUT, I still do not see any code that will actually receive an ultrasonic pulse.

            Also, your (PINE & 0x10) == 0) and (PINE & 0x20) == 0) are giving me a bunch of errors.

            Hopefully this is my last comment. I am sorry for bothering you on a Sunday.

          • My sensor uses the same pins to send and receive so I had to start a ping sequence for it to get into receiving mode where it stayed high until receiving an echo, the part you will need is more this part

            // The same pin is used to read the signal from the PING))): a HIGH
            // pulse whose duration is the time (in microseconds) from the sending
            // of the ping to the reception of its echo off of an object.
            pinMode(pingPin1, INPUT);
            pinMode(pingPin2, INPUT);

            delayMicroseconds(900);

            oneFire = false;
            twoFire = false;
            finished = false;
            setPoint1 = 0;
            setPoint2 = 0;
            difference = 0;

            while ((oneFire == 0) || (twoFire == 0)){
            if (((PINE & 0x10) == 0) && !oneFire){
            oneFire = true;
            setPoint1 = timeout;
            }
            if (((PINE & 0x20) == 0) && !twoFire){
            twoFire = true;
            setPoint2 = timeout;
            }
            delayMicroseconds(1);
            timeout++;
            if (timeout > 19000)
            break;
            }

            difference = setPoint1 - setPoint2;
            distance = (setPoint1 + setPoint2)/10;

            digitalWrite(13, LOW);
            return difference;
            }

            Your Arduino probably doesn’t have a PORTE, I was using an Arduino Mega

  16. One last thing. You say that I can use an unsynced transmitter. Does this affect any of my code or when I turn on the units? Meaning, do I have to turn both units on at the same time or does that matter?

    • Possibly. It depends on how your sensors work. The ones I used you did a sequence and then it started and would time out after a time. If yours do the same you could get out of sync. You might want to do a delay of some type on your readings so after a reading you don’t read for x mS so you aren’t just idling in your listening loop because you got out of sync of your transmitter.

      • I have been experimenting for a while now and have not found a solution. By now I have stopped trying with the motors and am focusing on the sensors. I still have not been able to have the transmitter be detected by the receivers. I have tried using the NewPing library and that has not worked. I posted on the Arduino Forums asking how to receive a ping on the hc-sr04 without pulseIn and all I got was “The PulseIn is blocking, it polls until line is changed.
        you should think of a rewrite of pulseIn() using pinchange interrupts.
        Not trivial but doable.” Any idea what this means or any further advice?

        • Did you try this code, replacing the PINE stuff with the echo pins of your sensors?
          oneFire = false;
          twoFire = false;
          finished = false;
          setPoint1 = 0;
          setPoint2 = 0;
          difference = 0;

          while ((oneFire == 0) || (twoFire == 0)){
          if (((PINE & 0x10) == 0) && !oneFire){
          oneFire = true;
          setPoint1 = timeout;
          }
          if (((PINE & 0x20) == 0) && !twoFire){
          twoFire = true;
          setPoint2 = timeout;
          }
          delayMicroseconds(1);
          timeout++;
          if (timeout > 19000)
          break;
          }

          difference = setPoint1 - setPoint2;

  17. I replaced the PINE & 0x10 with my echoPin1 (7) and PINE & 0x10 with my echoPin2 (6) and nothing else. Just to troubleshoot I had Serial.println(difference); and all I got was 0 when I pointed the transmitter at it. I feel like I am missing something. Was I not supposed to replace those with echoPin1 and echoPin2? As you can tell I am very inexperienced and would like to thank you again for helping me.

    • I have done some researching on port manipulation and have found that I can use it on an Arduino Uno. I just have to use PINB instead of PINE because my sensors are plugged into 6 and 7. When I replace your PINE with PIND I get no errors but still do not get any results. I think this is because of it not being synchronized. So unless you think otherwise my main problem now is a way to synchronize. Instead of using Xbee, couldn’t I just have an infrared led on the robot and an infrared sensor on the human that could communicate. Therefore I could be synchronized better. I have both of these parts available to me and it would not be that hard to get it to work I don’t think

      • Yeah, that would be a start. Maybe you should just try a singe sensor with limited code just to see how it works. I’m guessing that you need to start a ping for it to get into receive mode, so you are getting nothing because you are never in receive mode to receive a ping. Then after you are getting good results from a single one reflecting, remove its transmitter can and use a second sensor to see if you can hear the second sensor’s pings (you still need to initiate a ping with the first sensor). Watch in the video and that is what we do. One step at a time.

  18. In your PINE & 0x10 and PINE & 0x20 I know that PIN is a way of quickly reading the state of a pin. I also looked up that 0x10 = 16 and 0x20 = 32. Could you explain to me what these do. My setup is obviously different than yours so if I knew what they did, then I could probably figure out how to modify them for my setup. Also, I got 2 sensors to actually talk to each other so that is good. But that was using pulseIn which will not work in the final product so I need to learn how to use PIN.

    • Yeah, I’m going to write a post about that soon but haven’t gotten around to it yet, I’ll give you the short version. I frequently break out in hex, if you write that number in binary it will line up with certain bits with the port, its called masking. Instead of doing that, you can try putting this at the top of your Arduino file

      #define BIT(x) (1 < < (x))

      /* How to Use
      PORTA |= BIT(0); //ON
      PORTA &= ~BIT(0); //OFF
      PORTA ^= BIT(0); //TOGGLE
      if (PORTA & BIT(0)) //Read pin 0
      */

      #define SETBIT(p,b) (p) |= BIT(b)
      #define CLRBIT(p,b) (p) &= ~BIT(b)
      #define TGLBIT(p,b) (p) ^= BIT(b)

      /* How to Use
      SETBIT(PORTA,0);
      CLRBIT(PORTA,0);
      TGLBIT(PORTA,0);
      */

      Remember Arduino doesn't mark its pins by the bit number, they number them 1-20 or whatever, you will need to look at the schematic to see what pin of the port it actually is.

      *Note, you might need to use
      if (PINA & BIT(0))
      not sure if PORTA works there because its using as an input, try both ways, I think I've used PORTA when reading before and it worked but don't remember.

    • No, you are interested in the PD6 and PD7, those are bits 6 and 7 of PORTD. Just like Arduino output 9 is actually PORTB bit 1.

      So to read 6 you would do
      if (PORTD & BIT(6)){
      //code here
      }

      Make sure to put that code I have in the previous post (with the #defines) at the top of your file. Also if it doesn’t work for some reason, try PIND instead of PORTD . PIND denotes input but I think it will work with PORT as well in that code.

  19. For troubleshooting purposes I put:
    if (PORTD & BIT(5)){
    Serial.println(“5 pin received”);
    }
    if (PORTD & BIT(6)){
    Serial.println(“6 pin received”);
    }
    and got this error for both lines of the if statements: “expected primary-expression before ‘<' token."
    I did put the #define stuff at the top of the page so that is not the problem. Also, in you doPingDiff receiving code, can I just replace PINE & 0x10 with PORTD & BIT(5) and PINE & 0x20 with PORTD & BIT(6) for example?

  20. Not sure what your error is, I don’t even see a ‘< ' character in there. I did notice when I copied and pasted your code, it didn't work, gave me some other error though, the problem lied in the quotes, they didn't copy over correctly, they were a different character that looked very similar, strange. Maybe your problem is arriving from a similar situation and copying my code from above. I'll upload a text file with my header up there.

    As for replacing the code, yeah you should be able to, and I just checked, PORTD & BIT(5) does work, it doesn't have to be PIND. You might also want to replace my digital writes with SETBIT(PORTD,5) and CLRBIT(PORTD,5) instead as it is faster and should allow for less inherent difference when you start the ping process. Alternatively if you want to blow your mind, you can do both at once with
    PORTD |= 0x60;
    to set them and
    PORTD &= ~0x60;
    to clear them

    (bit header in txt file)
    http://blog.colecago.com/?attachment_id=341

  21. Thanks you so much! I am actually getting results and the whole project is semi functional. When I have the transmitter on the right side of the receivers, it gives me a negative number and on the left side gives me a positive number although there are many 0’s in between. I added this and quickly got the motors moving how I wanted them to:
    if (difference 0){
    right();
    }
    But when I add this:
    if (difference == 0){
    halt();
    }
    The motors get all choppy(on and off continuously). My goal is just to have the motors not move when the receivers are not receiving a ping. Any ideas? Also, I noticed that when the sensors are basically pointing at each other exactly straight, I get numbers close to 0 such as -4 and 4. Is there any way to have an if statement that will use this data to make the luggage go forward?

    • You should try and write your code to tell the difference between 0 difference and a timeout, then increment a counter or something for number of timeouts and after a specific amount, stop moving, but if you get a good signal, reset the counter. As for motor code, just for something simple, you can try


      Max = 255;
      if (difference >= 10){
      motorRight = Max - 25;
      motorLeft = Max;
      }
      else if (difference < = -10){
      motorRight = Max;
      motorLeft = Max - 25;
      }
      else{
      motorRight = Max;
      motorLeft = Max;
      }

      if (timedOut){
      motorRight = 0;
      motorLeft = 0;
      }

      Just an architecture, modify it to match your code and play with values, also not sure how well the Arduino compiler compares negative numbers. In the end, it would be better to have something like a PI loop, or even just a proportional difference in your motor adjustments, something like motorRight = Max - difference/10; but that is a little more advanced as it might need dampening, could be prone to oscillation, etc.

  22. For timeout code, I thought this would be easy and work well:
    if (difference == 0){
    counter++;
    }
    if (counter == 10){
    halt();
    }
    Every time difference was equal to 0, 1 would be added to counter and when there were ten 0’s in row the motors would shut off. I also set in all my other if statements that if difference isn’t equal to 0, then counter would be reset to 0. I have done some researching and can not figure out why this does not work. Once this is done, all the programming will be finished.

    • I don’t think I would use the difference of 0 to calculate timeout, if both ears hear it at the exact same time, then it will result in a difference of 0. I don’t know how your sensors work, but mine had a max number they would just return after even with no signal. I think I had timeout close to that, I had that counter going in the loop and if I counted up high enough I just said there was a timeout and broke out of the loop. Try something similar.

  23. Can anyone of you give me a parts list for the Xbee inverter. I have been away from digital electronics for too long.

    Much obliged with thanks.

    • The inverter in the show we used was a standard 74HC04 series inverter. We could have used a PNP transistor, but I had drawn it up wrong on camera, I have a correct drawing of it in the post. The Zigbee is in the parts list at the bottom of the post.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>