(Although I think this project may seem easy to some of you, for a coding noob like me who had no experience of coding before this class, I’m pretty proud of what I have done!)
I decided that for this week’s project, I wanted to work on my Earthquake text from last class – hoping that I could also incorporate Aaron’s suggestion of getting the background to move as well.
I started off with getting Processing to talk to Arduino first because I thought that in terms of the coding, it was easier for me to understand. I decided that I wanted to have some sort of “alarming” factor that happens when the Earthquake happens and what better way to catch someone’s attention by using blinking LEDs, right?
I wanted to write some piece of code that when the earthquake shakes, there would be an initial delay in the LED blinking to replicate the real-life situation (according to my geography studies, earthquakes are unpredictable and cannot be predicted until a few seconds before the earthquake and therefore when the earthquake actually happens, the alarms are already late). The blinking code was fairly easy, codes that we learned in the first week or two of class. I made it compatible with Processing, that when I pressed on the mouse, the letters would shake and the LED would blink rapidly. However, what I realised is that even though I did not have a delay at the beginning of the code that declared a delay in the blinking, the code did exactly what I wanted it to do. Cool, yay! I got something to work!
So came the hard part, and it all went downhill from there. My joy went from 100 to 0 real quick. It was time for me to get Arduino to talk to Processing. This process for me kind of felt like talking to a cat, sometimes it would respond but most of the times it wouldn’t care about you at all. Processing was the cat in this case. My next line of action was to connect an accelerometer to my Arduino and make it so that when somebody shakes my board, the letters on the screen shakes with the motion. To get to this goal, I needed to learn first how an accelerometer worked first (I got inspired to use this through Romeno’s project from a while back). I knew that from the accelerometer, I would get 3 different values for each reading, 1 for the x-axis, 1 for the y-axis, and 1 for the y-axis. I thought that it would be easier to take just one value for each reading, and stuck with just receiving the values in the x-axis only.
I got the accelerometer to work, found out the x-value in the initial position, but I didn’t know how to proceed. I knew I needed to write a piece of code in Arduino that would pick-up a large movement in the accelerometer. Aaron suggested that I could add the three axes together and keep a running count of the sum. Then if the difference between the current sum and a previous sum maybe 10 frames ago is greater than a certain threshold then that could be considered as a trigger. I thought that using the sum of the 3 axes was a good idea: first, there would be a larger difference in the sum every movement as it takes into account changes in all axes, and second, it would be easier to manipulate and use in terms of my code as it takes into account all types of movement of the accelerometer rather than simply the x-values that I was using before.
Okay, I got the sum. From there, I was once again stuck on how to proceed and use this sum. I decided to take a break from my code and actually draw out a flow chart of what my goal is and how I needed to get there through coding. I realised after a while that in order for me to get the letters to move through the movement in the accelerometer, I had to have some input that shows the change between the current sum of the axes and the initial sum. From the serial monitor in Arduino, I found that the initial sum was around 1074. The difference between the new sum and the initial sum would thus be something like difference = new sum – 1074. I realised I had to make this a variable and insert an if () function that would shake the letters if the difference is greater than a certain number. Inputting a random number and uploading both the code from Arduino and Processing, (here’s where everything was nice again) I REALISED THAT MY CODE WORKED! When I shook my board, the letters vibrated as well.
I wanted to implement the suggestion that Aaron gave me last week – to get the background image to vibrate as well. With help from a friend, I realised that a background wouldn’t be able to vibrate and rather I had to get the soil background to be an image that would look like a background but isn’t actually a background but only an image instead. I had to also make sure that the screen size and the image were different sizes, the image had to be bigger so that when the image shook, there wouldn’t be some vibration that would reveal the coloured background in the back. My friend suggested that I made the image shake using a boolean, meaning that it would either shake or not shake depending on the situation. I had to play around with the “translation” aspect of the image, changing numbers to make sure that when it did shake, there would be vibrations across the whole screen and not only at certain parts. The image vibration and shake that I ended up with has a random movement, like the letters.
VoilĂ . I did it. I actually finished my project.
To sum up what my project does:
- If you shake the board which has the accelerometer attached to it, the letters would shake and move around arbitrarily,
- While the letters are moving around arbitrarily, the background is also moving in a vibrating, earthquake-movement, random fashion,
- After a short delay of a second-ish after the earthquake has started, the LED would start blinking quickly and would stop blinking a second-ish after the earthquake has ended (replicating the real-life situation of alarms during earthquakes).
- (The space bar still brings everything back to the home position).
Here is a video of how it works:
Here is a screen-capture of both the letters and the background moving:
Here is the Arduino code:
void setup() { Serial.begin(9600); Serial.write(0); pinMode(2,OUTPUT); } void loop() { int sensorX = analogRead(0); int sensorY = analogRead(1); int sensorZ = analogRead(2); float sum = sensorX+sensorY+sensorZ; Serial.println (sum); delay(10); if(Serial.available()>0){ int inByte=Serial.read(); if (inByte == 1){ digitalWrite(2, HIGH); delay(10); digitalWrite(2, LOW); delay(10); if (inByte == 0){ digitalWrite(2, LOW); } } } int sensor = analogRead(A0); delay(0); sensor/=4; Serial.write(sensor); }
Here is the Processing code:
Main page:
import processing.serial.*; Serial myPort; import geomerative.*; RFont font; //PImage bg; PImage img; String message = "EARTHQUAKE"; int i; String val; Letter[] letters; boolean imageShake = false; int xPos=0; void setup() { //size(900, 600); size (800, 500); //bg = loadImage ("soil.jpg"); img = loadImage ("soil.jpg"); background(255); textSize (70); RG.init(this); font = new RFont("Courier New Bold.ttf", 1000); letters = new Letter[message.length()]; int x = 200; for (int i = 0; i < message.length(); i++) { letters[i] = new Letter(x, 280, message.charAt(i)); x += textWidth(message.charAt(i)); } printArray(Serial.list()); String portname=Serial.list()[4]; println(portname); myPort = new Serial(this, portname, 9600); myPort.clear(); myPort.bufferUntil('\n'); } void draw() { //background(bg); if (imageShake == true) { image(img, -50 + random(-25, 25) , -50 + random(-25, 25)); } else { image(img, -50, -50); } for (int i = 0; i < letters.length; i++) { letters[i].display(); // Display all letters } } float diff; void serialEvent(Serial myPort) { xPos=myPort.read(); myPort.write(0); String s = myPort.readStringUntil('\n'); s=trim(s); if (s!=null) { //int values[]=int(split(s,'\n')); float value = float(s); diff = abs(value - 1074.0); if (diff>25) { for (int i = 0; i<letters.length; i++) { letters[i].shake(); imageShake = true; myPort.write(1); } } else { for (int i = 0; i<letters.length; i++) { letters[i].secondPosition(); imageShake = false; myPort.write(0); } } if (keyPressed) { for (int i = 0; i<letters.length; i++) { letters[i].home(); } } } }
Class page (same as last week):
class Letter { char letter; float homex, homey; float x, y; Letter (float _x, float _y, char _letter) { homex = x = _x; homey = y =_y; letter = _letter; } void display() { fill(255); textAlign(CENTER); text(letter, x, y); } void shake() { x += random(-8, 8); y += random(-8, 8); } void secondPosition() { lerp(x, homex, 0.07); lerp(y, homey, 0.07); } void home() { x = lerp(x, homex, 0.01); y = lerp(y, homey, 0.01); } }
This project took me a very very long time. I would like to thank my friend, Navya, for explaining concepts to me and for helping me understand what the logic behind my project and helping me envision what my code needs to look like and ultimately helping me reach the end goal (aka this project). I think that I learned a lot about programming from this assignment, though it did stress me out a lot. Overall, I am happy with what the project turned out to be!