- Describe your concept
- Include some pictures / video of your project interaction
- How does the implementation work?
- Description of interaction design
- Description of Arduino code and include or link to full Arduino sketch
- Description of p5.js code and embed p5.js sketch in post
- Description of communication between Arduino and p5.js
- What are some aspects of the project that you’re particularly proud of?
- What are some areas for future improvement?
My idea was to creating an art piece using Arduino and p5 that lets user draw pattens on sand, something like this:
I was tempted to change my idea multiple times, because it just seemed too complicated to implement. But I’m glad I stuck with it!
The idea is that there will be something magnetic underneath the platform, hidden from view, and users will be able to move it using an interface. When the magnet underneath the platform moves, the steel ball above will also move with it, leaving patterns on the sand in its wake. In my case, I’ve made a four wheel robot that can go front, back, left, and right.
The white thing sticking out of the robot is a stack of magnets, raised to a height just enough to scrape the bottom surface of the platform. Here’s the Arduino code:
const int ain1Pin = 3; const int ain2Pin = 4; const int pwmAPin = 5; const int bin1Pin = 8; const int bin2Pin = 7; const int pwmBPin = 6; void setup() { Serial.begin(9600); pinMode(ain1Pin, OUTPUT); pinMode(ain2Pin, OUTPUT); while (Serial.available() <= 0) { Serial.println("0,0"); delay(300); digitalWrite(LED_BUILTIN, LOW); delay(50); } // set speed analogWrite(pwmAPin, 255); analogWrite(pwmBPin, 255); } void loop() { while (Serial.available()) { int left = Serial.parseInt(); int right = Serial.parseInt(); if (Serial.read() == '\n') { if (left == 1 && right == 0) { analogWrite(pwmAPin, 100); analogWrite(pwmBPin, 255); digitalWrite(ain1Pin, HIGH); digitalWrite(ain2Pin, LOW); digitalWrite(bin1Pin, HIGH); digitalWrite(bin2Pin, LOW); } if (left == 1 && right == 1) { analogWrite(pwmAPin, 255); analogWrite(pwmBPin, 255); digitalWrite(ain1Pin, HIGH); digitalWrite(ain2Pin, LOW); digitalWrite(bin1Pin, HIGH); digitalWrite(bin2Pin, LOW); } if (left == 0 && right == 1) { analogWrite(pwmAPin, 255); analogWrite(pwmBPin, 100); digitalWrite(ain1Pin, HIGH); digitalWrite(ain2Pin, LOW); digitalWrite(bin1Pin, HIGH); digitalWrite(bin2Pin, LOW); } if (left == -1 && right == -1) { analogWrite(pwmAPin, 255); analogWrite(pwmBPin, 255); digitalWrite(ain1Pin, LOW); digitalWrite(ain2Pin, HIGH); digitalWrite(bin1Pin, LOW); digitalWrite(bin2Pin, HIGH); } else if (left == 0 && right == 0) { digitalWrite(ain1Pin, LOW); digitalWrite(ain2Pin, LOW); digitalWrite(bin1Pin, LOW); digitalWrite(bin2Pin, LOW); } int sensor = analogRead(A0); delay(5); int sensor2 = analogRead(A0); delay(5); Serial.print(sensor); Serial.print(','); Serial.println(sensor2); } } digitalWrite(LED_BUILTIN, LOW); }
Front and back motion is fairly simple — all wheels turn at full speed in the same direction. For left and right, I could’ve just made the wheels on one side turn. But I tried this out, and this created strange 360 degree motions. While the robot was turning, the ball on top of the plane wouldn’t move much. This created a strange user experience. So I thought of the velocity differential of each wheel with respect to the other. If the wheel on this side moves faster than the other side, the robot will turn nicely to this side. That’s how real cars work anyway. I ended up going with this logic, and the ball/robot’s motion is now much much smoother.
I was going to just use two wheels on each side. Two motors work fine with Arduino, as we’ve seen in class. In my first prototype, I had only two wheels, that wasn’t enough power, and the robot’s motion was very slow. So I tried to add two more, but it wouldn’t work, even with another motor driver. The Arduino wouldn’t turn on with four motors and two motor drivers connected. I realized that I didn’t need all four wheels to act independently — the front wheels could just imitate the pair at the back, or vice versa. So I plugged in each front wheel in series with the corresponding back wheel, and it worked great!
On the p5.side, things are much simpler. Here’s the link to the full code.
The user can control the robot’s motion by dragging the mouse, and it creates ripples like this:
I wish I could’ve made the magnet attachment better, though. Right now, it’s just taped to a bamboo skewer, stuck into one of the Sparkfun kit baseplates. A better way to do this would be to make an attachment specifically for this purpose.