Let's Make Robots!

Mappy (the mapbot)

Environment mapping (soon I hope)

mappy_1.jpg

So after putting together and taking apart a few prototypes starting with this ugly mofo I'm finally arriving at something I like. It's a simple start here class sorta robot allthough it has a specific purpose which is: environment mapping. Therefore it is outfitted with a pair of homemade wheel encoders, so that I can measure how much the wheels are turning, and thus calculate how far it is moving. I'm having a hell of a time getting the encoders to work properly though. These IR sensors are very sensitive and the slightest change in light, distance or angle messes up my readings :(

Anyway for now I'm calling it Mappy. I'm also considering simply MapBot. Or perhaps RoboBob. My girfriend thinks it's extremely cute and wants me to name it after my petname for her which is Miti. Perhaps Miti2.0 has a bit of a ring to it :D

In the process of creating this bot I had to make a shield for my Arduino, which has now been expanded to connect the two QRB1134 sensors for the wheel encoder. Here are the parts of my robot separetely:

patrs_1.jpg

parts_2.jpg

Future plans for Mappy..well 1st of I wanna get the encoders to work smoothly, and then start doing some PROGRAMMING!! Wheeepeeee!! But I'm also planning to add two frontal bumper sensors and at some point I wanna add an extra servo to make a pan and tilt mechanism for the IR sensor AND I wanna add OddBot's compound eye too (I bought one when I ordered a bunch of motors and servos recently).

For now it's powered by an AT power supply and sends the mapping data to my PC via USB, but I'm planning to get 4 x NiMH AA batteries and a bluetooth module ASAP to make it truly mobile.

 

.....:... Aniss

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Basically that's what I do. Only my "state" variable is called "old_val" instead.

The timer is an ugly workaround indeed and I certainly don't intend to keep it. I was just trying out different ways of making it stop counting some transitions more than once when I connect it to a digital input. I could off course use the analog input and use thresholds to detect the transitions, which would be infinately better than the current workaround. As you can see in the last scope screenshot the readings are good enough for that. But I would very much like to make it work with a digital input so I can use the hardware interrupts (on Arduino's pin 2 and 3). That would be the optimal solucion because it would minimize the possibility of missing transitions when I start adding more code into the main loop.

And yeah the 39 vs. 38 is just plain weird as you say... :/

It has been really hard to get the encoder to stop occasionally counting transitions more than once. But I just had a rather succesful run at that. My test setup is simple. I put a small piece of red sticky tape on the wheel so I can see when it has performed a full rotation. I then start counting steps and every time it made a full rotation I stop for ~2 secs. I let it run for some 10 minutes and it only got misplaced by a few millimeters. Best so far.

Here is the (rather ugly) code I used:

----------------------------------------------

int val;
int old_val;
int count = 0;
unsigned long int time;

void setup() {
  Serial.begin(115200);
  Serial.print("START"); // sync with scope
  pinMode(2, INPUT);
  val = digitalRead(2);
  old_val = val;
  time = millis(); // initialize timer
}

void loop() {
    analogWrite(5, 100); // move motor
    val = digitalRead(2);
    if(val == 1) val = 255; // max scope value
    //Serial.println(val); // serial monitor
    Serial.print(val, BYTE); // scope
   
    if(val != old_val && millis() > time+5) {
       if(count < 38) {
         count++;
         old_val = val;
       }
       else {
          count = 0;
          delay(5);
          analogWrite(5, 0);
          delay(2000);
       }
       time = millis(); // reset timer
    }
   
    delay(1);
}

----------------------------------------------

As you can see I had to make a rather nasty workaround to get it to stop counting some transitions several times. I only count a change if minimum 5 millisecs have past since the last change:

if(val != old_val && millis() > time+5)

Besides that it's rather odd that I'm using an encoder wheel with 40 clicks per rotation BUT I seem to be only counting 39 clicks per rotation:

if(count < 38)

When I tried it with 39 as it SHOULD be it simply didn't work?! Strange :/

I guess making your own encoder isn't that easy at all. I still have some tweaking and fiddleing to do but it's starting to look like something :D

Aniss .. Over and out

I've seen another discusssion about coding to read a rotary encoder, which suggested a few algorithms. One that was somewhat agreed upon was the use of state machine programming to keep track of counts. Essentially what was needed was to keep a small local memory of what the encoder was last time through the loop, a small "state variable. If the new value read was different than the current "state" variable, then the count could be incremented and  the new "state" recorded. 

The timer you've used seems worrisome, in that it would appear to skip counts if the robot got moving too fast. odd about the 39 thing. 

OMG IT'S WORKING :/

I have no idea what was wrong before though because I started all from scratch again...that is rewrote the code and rewired the circuit on a different part of my breadboard using different resistors and mostly different jumper wires. So now I'm getting beatyful HIGH/LOW readings:

high_low.jpg

At some point I will try to find out what was wrong before but right now I'm more interested in seeing what I can do with these readings. :P

Thanks for your help and patience and sorry if I've wasted your time unnecessarily (TeleFox). If it makes you feel better it's nothing compared to the HOURS I've wasted myself probably because of some silly noob mistake :/

Most of the stuff I wrote was just generic electronics, worth knowing anyway. What resistor value/s did you use in the end? No doubt Rudolph and others using a similar circuit would be interested.

Also, what is the difference between the high and low voltages? The levels are quite nice, but of particular importance is how clean the transitions are, that should make processing the encoder pulses almost trivial.

The screenshot you see is based on a 220 Ohm LED resistor and a 20K pullup and a 1uF cap. I didn't even try other resistor values yet to see if I can improve it but I did try it without the cap which gave pretty much the same result so I think I'll just loose it alltogether.

The voltage levels differ A LOT according to the light in the room. In particular the HIGH signal changes over 1V when I turn on/off my lamp. And I didn't even try it in daylight yet. I suspect this could be the source of Rudolph's problems. He's doing his testing/calibration with the servo open and when he closes it up everything changes.

Anyway each square in the background grid of my homemade oscilloscope represents 1V. The LOW signal is damn close to cero (around 0.1V) and the HIGH signal is around 3V when the lamp is on (as in the screenshot) and 4V when it's off. But I may be able to improve on that with a little fiddleing around.

Allready now the signal is clean enough to make an encoder work using the analog readings :D But I think I'll still try to connect the Scmitt-thingie to see if I can get it closer to a nice squarewave that can trigger a digital input steadily. This would be ideal because then I could use interrupts to detect the transitions.

I've now tried to hook up the pot instead of the pullup resistor. Just wanna double check that I've got it right..

The pot looks sorta like this:

pot.jpg 

* The pot has 3 legs. 1st is for power, 2nd is for ground and the 3rd (the middle one on the opposite side of the others) is the wiper. Is this correct?

* I suppose that it isn't polarized so it doesn't matter if I interchange the ground and the power pin?

* I suppose that the 1st replaces the high side of the resistor, while the 2nd is connected directly to the ground, and the wiper must replace the low sid?

* The pot has a range of 1K to 100K. When I hook it up and pull it to one extreme I get all zero readings no matter what I do with the sensor. I suppose this is when it's at its minimum (1K)?

* When I pull it to another extreme I get readings like this (fluctuating rapidly between 5V and 0V):

pot_high.jpg

I suppose this is when the pullup resistor is 100K. Isn't it strange though that it doesn't just stay high instead of fluctuating like that?

That's it for now :)

• Yes, middle leg is the wiper. How you connect the other two depends on the application - if you just want a variable resistor then you often leave one leg disconnected.

• If it's polarised then it's not a resistor =)

• Are you talking about using it to bias the phototransistor for the IR detector? If so, you'll want to connect one of the outer legs to V+ and the wiper to the top of the phototransistor, leaving the other leg out of the circuit altogether.

• It really depends how the whole circuit is wired up - either way you likely have a large resistance between the analog input and V+.

• Potentiometers often have poor contacts when they're turned right to the limit, this may be the cause of the fluctuations.

The 74HC14 Schmitt Trigger Inverter is an IC that I've used many, many times. Very handy little IC. Go to Octopart.com or somewhere like that and grab a datasheet; if you have any questions after having a look there let me know.

As usually you're the man..unfortunately I'm not so I'm still unclear about some things...

* OK! I only want a variable resistor!

* Didn't think so..check!

* I'm simply trying to replace the pullup resistor with a variable one so I can fine tune the setup. So it seems I should NOT have connected the 3rd leg directly to the ground as I did (which means I spent an hour of testing with a flawed circuit).

* I'm using the exact same circuit as before only with the 10K pullup resistor replaced by a pot (1K - 100K):

 qrbsetup.jpg

* I'm afraid that isn't the case. If you look at the scope screenshots I've posted earlier you'll notice that I've been getting these EXTREME fluctuations all along (with the fixed resistor also). I haven't been able to get a pure high signal at any time. It constantly fluctuates between cero and a high voltage no matter what I've done. That seems to be my problem.

PS: I've allready got the datasheet for the 74HC14 and I found some examples on how to hook it up in similar setups. I'll be studying those and then probably I'll come back and ask a question or two :D

PPS: Are you SURE that it isn't the WIPER I should leave out of the circuit?

Ok, so to use a pot as a variable resistor you want to connect one leg to V+ and the wiper to the top of the phototransistor (collector terminal). If you were to connect both outer legs and leave the wiper disconnected, you'd have a fixed resistor, with resistance equal to the maximum resistance of the pot.