So the learn.parallax.com site already has code up for the joystick and servo control. I thought I’d try to control two servos with a single joystick, and eventually have an Emic2 say what direction I was moving in as well.
There are a couple of examples there - one showing a voltage range and another converting that voltage range into a value between -100 to 100. So usually I would make the serial terminal write out Up, Down, Left, or Right depending on the range. Let’s see…
It’s a little repetitive, but it does what I want it to do. And now I’d like for it to speak what direction it’s going in… That requires getting the Emic2 to work! [after a couple of hours…] Okay! Never mind, lol. I’m going to get the servos functional first!
So the code given http://learn.parallax.com/propeller-c-simple-devices/standard-servo didn’t work for me. The servo just kept going in one direction before stopping. I looked back at what I had to do for servos in spin: http://tymkrs.tumblr.com/post/16868667432/parallax-rc-servo-part-ii-code-analysis-1-2 and I remember having to figure out how many milliseconds to send to the servo to tell it which direction to move in. So!
Basic Servo Troubleshooting: http://pastebin.com/t6mmANP9
I wanted it to go left (counter clockwise), stop, then right (clockwise). After messing with the numbers a little, I realized that sending 1020 or 1025 to the servo (depending on which one), would stop it. That less than the 1020 = counter clockwise and more than the 1020 = clockwise.
So once I had that, I got one servo working: http://pastebin.com/c413VByH
This one - if you go up or down on the joystick, the servo goes counter clock or clockwise, relatively speaking. And if you go left or right, it stops the servo.
And then I wanted to finally control 2 servos: http://pastebin.com/hPUdQwef
If I can figure out how to get the Emic2 working - I will!
Last week on FirstC, we went into looking at simple devices and sensors that would could use with C on the Propeller. I wanted to cover one that had a learn.parallax.com page for it and one that did not. So easiest sensor for me personally is the Ping, and I decided to add a PIR sensor.
Previous lesson on the Ping:
Previous lesson on the PIR:
The goal was to have a PIR activated Ping sensor. This may help to conserve battery life, or in general have more relevant data. So if someone comes into a house, the Ping activates and you can find out roughly which door the person’s coming in from. (Or just use a real system :))
But here’s the code I used: http://pastebin.com/G0dfGFQr
So taking advantage of the Ping header that Parallax has already written made it easier to get the ping to work. But here you can see that first, we’re letting people know that the PIR is warming up - about 20 seconds.
Then we go into what is essentially a repeat loop (while (1)) where an integer variable PIR is created and set to monitor the input of pin 14. If PIR is found to equal 1, then we go about getting information from the ping sensor and save it to an integer variable, cmDist. Otherwise, we just loop back around watching for PIR to equal 1.
And when you run the code…
You can see that initially there was no motion detected so the PIR sensor registers as 0 and the ping doesn’t have to send any information. But as soon as the PIR sensor senses movement, then bam, the Ping sensor sends information.
Hopefully this is the last iteration. But there are a few things that we needed to add.
1) A switch so that power wouldn’t constantly be drained from the batteries. So to run it, you’d have to push the switch down, wait a little, and then blow.
2) We needed to change the load resistor from 200k to 10k. Wasn’t sure if I showed that on the last schematic.
2) It was suggested that I make the LEDs less bright so that we wouldn’t be drawing so much current. This too will help with saving battery life.
So! With a few tweaks here and there:
You can see the added switch, and the changed resistor values. Now I know I did a whole thing on how between pins 7 and 8 there was this ref + 1.25v thing going on. @wireengineer says it’s just a nominal 1.25V no matter what any of the other refs are. I’m just going to accept this :p.
So! With V=IR and V = 1.25V…..the leds are getting 10.4mA with 1.2k resistors which seems to still be quite bright. So I’m going to get a few other value resistors and see how that goes!
Circuit design, never a dull moment!
The funny thing about the Drink Me is that it’s a miracle that it actually works. After the folks in the tymkrsIRC took the schematic apart they had some choice words:
"This is one of the least readable schematics I’ve seen to be honest" ^o^
So there were clearly some issues with that schematic. And we decided to change things around.
- First I added an extra LED to take advantage of the fact that the LED bar driver can drive 10 LEDs.
- And then instead of having a potentiometer that could calibrate the signal, I put a load resistor. Now according to the datasheet, it needs to be 200k. So that’s what I drew up. I still kept the calibrating potentiometers for the loref and hiref
I got it soldered up and everything. And then all of the lights stayed lit no matter what I did to calibrate things. According to insurgent’s research he found another person who said “The MQ-3 datasheet says to use a 200K ohm resistor, but anyone who’s used this sensor knows that this constrains the measured voltage to a tight, high range. I recommend a 10K ohm resistor.”
"The datasheet for this sensor shows that the resistance across the sensor is between 2K-20K ohms, so an RL value of 10K ohms will provide a wide voltage output range."
There’s also a few ways you can see if something’s wrong with the load resistance - to see if there’s too much. First take out the led driver chip. Then look at the voltage coming from the sensor and compare it to Vcc when you have no alcohol and when you do. Put one probe to GND, and one probe to pin 5 (signal line on the LED driver). I got 4.55 volts for both what was coming from the sensor and for VCC. Per @insurgent: “With 200k load you are only going to have a range of like 4.5 to 4.9 with 5v supply”
SO! We changed it to a 10k. Now that wasn’t the easiest thing because apparently I’m a bit of a barbarian when it comes to desoldering SMT components and I totally lifted the pad off when I desoldered the 200k resistor. Whisker suggested I scrape off some of the purple soldermask from the wire that the messed up pad was supposed to connect to, and then connect with some solder. So we got the 10k connected that way, thanks @wireengineer!
And then we measured things again - still with the LED driver chip out. One probe to GND, and one probe to pin 5 of the socket (which is where the sensor’s signal would meet the LED driver chip). Once without alcohol, and once with.
Without alcohol we measured: 2.32v….140mA being drawn by the circuit
With alcohol and all lights on: 4.35v….>200mA being drawn by the circuit
So after tweaking the lo ref and hi ref potentiometers, we got it so that it reacted appropriately to alcohol being in the air! Wahoo!
Yesterday we got to look through the example code of a multicore example. But as all good tutorials do, they try to encourage you to do a number of things.
A lot of times, people ask how you know what cog is being used. Handily enough, you can simultaneously launch a cog AND assign it to a variable. Here they name it cog, and as you launch the cog, you can also see what cog it is you’re using. Nice!
So the goal for our challenge is: Add a subtracter function to the project and launch it into a third cog. Make subtracter decrement a new global variable with the same initial value as n, repeating every t ms. Display the changing values of both variables.
http://pastebin.com/0ZqPXKVW is the code I came up with!
I think with this done, we’re going to get into the sensors and peripherals that Parallax has to offer and how to code those up in C!
One of the reasons we enjoy using the Propeller so much is that instead of interrupts, you get to send a different cog an activity. So you essentially have the ability for 8 different processes to happen simultaneously. It is what makes the Propeller so powerful.
So for this example:
Um. Alright, so we have a forward declaration letting us know we’re going to have another function called adder. It is defined as not needing a result nor giving a result. (Q: What’s *par)
So then we have two integer variables t and n. They also have a side designation of being “static volatile”. Seemingly an oxymoron, according to the tutorial, it means that this variable is a global variable that can be used between cogs.
The next line says “unsigned int stack [40 + 25]”. It looks like this is where you set aside 40 longs for the memory, and an extra 25 longs “just in case” for variables and such. I’ll see what’s said during FirstC for all of this.
In the main function, the first thing we do is set variables t and n to integers. We then send a function into another cog:
cogstart(&adder, NULL, stack, sizeof(stack));
So. Cogstart starts another cog. Sends in &adder (the address of the function). Then an optional value (or NULL). It then sends the address of the stack array which we had called “stack” earlier - very creative. I think this is probably the amount of memory that the new cog will be allocated. And then the size of the stack array, which we can just use “sizeof(stack)” to denote. Handy sizeof capability!
Okay and then we have a while statement that says welp, let’s see what’s the other cog is doing to n.
And then if we look at the adder function called…”adder”, it’s just incrementing n by 1 each cycle, and waiting for t milliseconds, which in this case is 50.
So a bunch of the previous examples were using local variables (ones that you declare within for loops and specific functions). But now we’re looking at global variables.
In this example, we have globals a, b, and n. We set what their values are in main, and then go to the adder function which gives us the value for n. We then print n from the main function.
- Modify this program by creating a subtracter function that uses the global variables, and add some code to your main function to test it.
is our next lesson for the day. So let’s see…
Ahh the meaning of life :) So it looks like in this code, we’re setting up an integer n to equal the result of a function named adder. We’re sending 25 and 17 into adder and what it’s doing is taking those numbers and getting their sum, then returning a value from adder to where it was called from.
Couple of cool notes:
- The function’s parameter list is not your only chance to declare local variables. The main function’s int n =… and the adder function’s int c = … are also examples of local variables.
- The adder function could have been even shorter. You could replace the two lines in its code block with return a + b; no need for int c at all.
So here’s the next iteration.
It looks like here we’re having adder return multiple results even after going through manipulation and it looks like it’s doing it easily!
- Add a forward declaration for subtracter above main.
- Add the subtracter function (which subtracts a from b) below the adder function.
- Call the subtracter function from within main.
In yesterday’s post, we introduced void, which allows a function to not have to return a value. But what if you do want it to return a value or put a value into a function? Well that’s this lesson!
It’s always good to look at the code that you’re running and thinking about what it’s doing. First you see that void is “set up” such that its name is value and expects “int a”
In the main function, the function calls for value(6) - int a = 6 in other words. And as such, the function will plug in 6 into a and display that. Note, you don’t have to write “void value(int a)” you can just write “void value(a)” since it was already determined to be an integer earlier.
In this code (http://pastebin.com/eZ9w35hp) , it’s showing that even though both functions (value and two_values) are using “a” as a variable, they are treated as local variables and do not interfere with each other. Here’s the lesson:
- Write a function definition of void counter(int startVal, int endVal, int incVal)
- Add a for loop to the function that starts counting at startVal, stops counting at endVal, and takes steps of incVal. HINT: Your for loop should start with for(int i = startVal;…
This confused me a bit, see: http://pastebin.com/WaS25kak - it wouldn’t compile. So I changed things around a little bit: http://pastebin.com/qtsjUd2z. It compiles now, but Value = 0 the entire time. So that’s obviously not what I want it to do!!
I’ll come back to this after we record First C haha.
So after finishing the HeartMe, I thought it’d be hilarious if I could do some sort of OrganMe series. And naturally thought about the liver, because well, alcohol is processed through that and what better way to test for alcohol than with a breathalyzer. Now I’ve never seen one or needed to blow in one because I’m not really a drinker, but I thought it’d be funny to make one.
And then I looked at the liver. And it is an uuuggggly organ. Like, awkwardly shaped and I’m not sure I’d buy my own liver-shaped board, so I thought, next best thing, wine bottle!
I decided to use the MQ3 sensor which is this widely accessible, hard-to-calibrate sensor with a datasheet with too little information. The main things that I can tell from the datasheet is that it works off of 5 volts and that before it works I need to power it for at least 24 hours. Connection wise, we’ve got this schematic to work off of:
So I can choose either A or B to hook up to a DC5V source and then the opposite to hook up to something that can read the signal as well as a potentiometer RL which should be according to the datasheet, around 200k.
One thing I wanted to do was of course incorporate LEDs, and I’ve had a little bit of experience with the LM3914 and so I thought I’d used it to drive a bunch of LEDs. No problem right?
Here’s my schematic. With the help of JohnS_AZ we added a couple of calibrating potentiometers. RV2 calibrates RLo and RV3 calibrates RHi. It’s like changing the range of what voltages the LED bar driver shows. I however added RV1 because I thought I’d calibrate the signal.
When I put it together, it actually still worked! (https://www.youtube.com/watch?v=mhxA_tR6Lj8 2 minutes in)
Now, there are a few things that are super wrong with this schematic.
- Good practice is to label the pins of the ic with the pin’s function so you know what pin is doing what.
- This led driver drives 10 LEDs. I only have 9. And pin 1 of the LM3914 is supposed to drive a LED, but I have it going to V+…woops. Essentially, if you have too much alcohol, it shorts out the power!
- RV1 is pretty much unnecessary because on both the schematic and the board, the signal from the sensor is essentially going into LM3914 pin. Potentiometer RV1 is essentially just biasing the signal. I should instead just have a 100-200k resistor (like what the datasheet says I should have). Though I will probably go for fixed instead of pot.
It is however pretty!
But I would like it to work and you know, not short out :p. So I’m going to make those changes and then we’ll try again!!