Write an application that interfaces with an input &/or output device
There are two things I want to try to solve with this week's
assignment...
1) Show a computer GUI that simulates my bounceback that will show
two parts of the UI: Whether someone hits the tile with a ball and
how hard they hit it, and
2) Experiment with changing the AREF (analog reference) for the
AtoD converter. In talking to Shawn, we realized that it
would be helpful to have the analogRead comments measuring the
small change in the impact of the ball on the velostat.
Right now the signal comes in around 44 when I do the analogRead
in a steady state and when the ball hits the velostat the value
goes to 60. This means it is hard to read with any kind of
accuracy whether the ball hit and there's little variability in
the values. By changing the AREF value down to something
like .5v (instead of the standard 5v), I will get more precise
readings.
While I realize that #2 isn't specific to this week's assignment,
I figured I need to work on this for the final project and it
would be cool to get the screen output adjusted so that it's be
more obvious when someone hit the velostat. Without this,
the changes in the barchart I plan to show would be imperceptibly
small if I was using the standard AtoD converter with 5V as the
reference point.
Get Voltage Divider Wired and with right values
|
|
Get Arduino with Different AREF valueOnce I knew I could get 0.45 volts out of a simple voltage divider, I needed to figure out how to get the Arduino reading that value and changing the AREF. That brought me to the analogReference reference documentation. The following sentence messed me up: Note that the resistor will alter the voltage that gets used as the reference because there is an internal 32K resistor on the AREF pin. The two act as a voltage divider, so, for example, 2.5V applied through the resistor will yield 2.5 * 32 / (32 + 5) = ~2.2V at the AREF pin.LEARNING: Read the data sheet first This suggested all my prior work was useless because the Arduino hardcoded a 32K internal resistor. That meant I needed to change the values of the resistors I was going to use for this. My new math to figure out the "top side" resistance was: 32K (internal resistance) / (32K + X) (total resistance)= 0.45 (target voltage) / 5V (total voltage)To test this theory, I wired up the resistors on a breadboard with a 33K resistor on one side and three 100K resistors on the other and used the voltmeter to check what the voltage was at the mid point between all these resistors. I did two tests... - I set it to 200K ohms to check for resistance and checked that three 100K resistors in serial delivered 99K of resistance - I set the voltmeter to 2K Volts to check for total volts to make sure that I had about .45V coming of the center point |
|
Get Processing Interfacing with Arduino through Serial PortTo get this going, I started by reading through and watching some tutorials about Processing. Here were the most useful ones: - AS220 tutorial - Processing tutorials - OpenProcessing tutorials - Arduino Writeup for Communicating with Processing LEARNING: Serial Communication requires Serial.write (instead of Serial.print) When trying to get the Arduino to communicate with the computer/processing engine, you can't use Serial.print because it will convert everything to it's ascii value. When writing serial out of attiny/Arduino, you need to use Serial.write, not Serial.print so that it sends a byte with the exact value (and not the ascII version of that value). If use Serial.print(8) it will send the ascII value for the number eight (58). If use Serial.write(8) it will send the value 8. The reading reads one byte at a time. LEARNING: Be sure to send BYTEs not ints So I got the Arduino sending data (the results of a sensor reading) and it wasn't working. I thought the values it would be sending would be in the 600 to 900 ranges. Instead, it was getting the resting value of ~200 and when I put pressure, which increased the values coming from the sensor to the 800's, the values dropped to between 0 and 100. Clearly I was missing something. So I changed geers and started sending constants (10, 100, 500, 1000) using the following: void setup()Using this draw routine: void draw()Two issues show up with this: 1) Why are there six values for each Serial.write command? I would have thought that it would only show one line per. 2) Send int's differently. Instead of 10, 100, 500 and 1000. That's when I found the following article on that helped me understand more of this: interpreting serial data, how serial data works and http://arduinobasics.blogspot.com/2013/04/serial-communication-tutorial-part-3.html. This led me to the following conclusions: FIX #1: the draw() routine was running really quickly so the value was being set and it was continually running until and printing out the value without being cleared out. The fix was to set the received value to something like null or zero so that it wouldn't continue to act as if it had gotten a new value. Basically, draw() go so quickly you need to have it handle the value and then move on. FIX #2: I need to convert individual bytes to integers. Either I should read individual digits and convert them to integers (as suggested in this artcle) by doing some math like this: integerVar = (byte1Var * 256) + byte2Var. Or by doing something like I am doing below where I am parsing out the digits and using the int() call. FIX #3: It took some time, but I got things working with the serial.event call. Here is my code that received information from the serial port and then processed it according to teh type of information that was passed: // NOTE: This started with an example by Tom Igoe...And here was the Arduino code that was sending my examples: /* |
Here's the initial output: Got 10 from serial port Got 10 from serial port Got 10 from serial port Got 10 from serial port Got 10 from serial port Got 10 from serial port Got 100 from serial port Got 100 from serial port Got 100 from serial port Got 100 from serial port Got 100 from serial port Got 100 from serial port Got 244 from serial port Got 244 from serial port Got 244 from serial port Got 244 from serial port Got 244 from serial port Got 244 from serial port Got 232 from serial port Got 232 from serial port Got 232 from serial port Got 232 from serial port Got 232 from serial port Got 232 from serial port |
Get Processing to Show Bounceback UILEARNING: PShape objects require P2D rendering engine with size command for main window I had code that was using the PShape command. It wasn't working when I tried to "setfill" and I got the following error: createShape(), or this particular variation of it, is not available with this renderer.I then saw some examples that added the P2D command to the end of the size command. When changed the size command from: size((bouncebackTileSize * 2) + (marginSize * 3) + (tileSpacing * 2), (bouncebackTileSize * 2) + (marginSize * 2) + tileSpacing);to size((bouncebackTileSize * 2) + (marginSize * 3) + (tileSpacing * 2), (bouncebackTileSize * 2) + (marginSize * 2) + tileSpacing, P2D);...all started working with the PShape object and the colors. LEARNING: draw(), redraw(), loop() and noLoop()...the matter I kept running into issues with code running so quickly. I finally read through the reference on draw(), which said the following, and it made immense sense. Once I started using redraw() and noLoop() I started getting the right flow in the program. Called directly after setup(), the draw() function continuously executes the lines of code contained inside its block until the program is stopped or noLoop() is called. draw() is called automatically and should never be called explicitly. It should always be controlled with noLoop(), redraw() and loop(). After noLoop() stops the code in draw() from executing, redraw() causes the code inside draw() to execute once, andloop() will cause the code inside draw() to resume executing continuously. The number of times draw() executes in each second may be controlled with the frameRate()function. |
Above is the Processing window/visual with the look of the bounceback where I will have four 6"x6" tiles that will light up for kids to know that's the tile to aim for. Then on the right will be an LED strip that will light up based on how hard the ball hits the tile. |
FINAL RESULTS Next I turned my attention to drawing the UI and getting things working. Things were going great, until I got a java exception engine and processing screen / java started crashing. I started getting the following errors. For whatever reason, it started dying on "shape" call in the setTileColor routine. I tried debugging it all, but couldn't find anything. +++++++++++++++++++++++++++++++++++++++++++++ Java Runtime Error when crashed: # A fatal error has been detected by the Java Runtime Environment:+++++++++++++++++++++++++++++++++++++++++++++ Processing Engine Code: import processing.serial.*; ++++++++++++++++++++++++++++++++++ Arduino Code Sending Hit Info /* The following Wiring/Arduino code runs on both microcontrollers that were used to send data to this sketch: */ void setup() { // start serial port at 9600 bps: Serial.begin(9600); } void loop() { delay(100); //Serial.write("c"); Serial.write("M\n"); Serial.write("11023\n"); delay(5000); } |
|