like what Merce says in response to the question about the division between Ballet and Modern Dance. It's not a division to him, he wants to know how does one make it?!! That's exactly it, that's what you should be doing, not working at the level of interpretation, but in the process of discovery and experimentation.
---> engage in a process of discovery with moving objects that reveals interrelationships of visual space and time.
david bohm , a physicist, coined the term rheomode, after observing that language, by its very nature takes the form of a 'stop-motion' interpretation of events, as they entail a level of differentiation both from the qualities of the events described and the nature of the environment in which they take place. This is generally agreed to be hard-wired into language at the cognitive level and in part arises due to language dividing perception into several classes of words - noun, verb, adjective, and so on.
he developed ‘rheomode’, a mode of language which aims to move the language away from a stop-motion image of reality, in which flows and processes are viewed only as a series of stages or pictures, to a continuous process of engagement with the qualities and contexts of given moments to participate in a more flowing, continuous, process-related conceptualisation.
The implications for the thought processes of this mode are to bring one’s mind closer to a view of the world as continuously flowing from one scenario or reality to another. This is in contrast to natural language modes, which view reality in a series of stop-motion still images.
By way of an example, we could ask the age-old question "Which came first, the chicken or the egg?" Natural languages are essentially unable to answer this, as their stop-motion function is largely unable to successfully parse the event implied in the question. Most people, who effortlessly speak their natural language(s), will therefore select either the chicken (who laid the egg), or the egg (which hatches the chicken) as the originator of the species and therefore the correct answer. The 'rheomode', however, provides us with a different view: The chicken and the egg are all aspects of the same being and evolved together slowly over time as part of a naturally selected process. At no point did a hypothetical 'non-chicken' become a 'chicken', but gradual infinitesimal gradations from one state to the other occurred. Therefore neither, strictly speaking came first. This, then, is the essence of the rheomode.
The idea for this concept and method of perception came from David Bohm’s book 'Wholeness and the Implicate Order' in which he postulates that both quantum and macroscopic realities are nonlocal and unified by an implicate order. This implicate order is likened to an enfoldment (or series of enfoldments) of the fabric of reality in which matter, energy, space and time are expressed by the means of un-enfolding this order so that they become explicate.
Bohm likens this ‘explicating’ process to stirring a spot of ink in a viscous liquid like honey. One puts a spot of dark ink into the honey (and thus the spot of ink is a metaphor for a ‘particle’ such as an electron, or for a quantised area of space, time or energy), and beings stirring. The spot of ink is at first stretched out into a circle, then is slowly smeared across the whole of the honey. Thus the spot of ink can now be said to be nonlocally distributed across the honey, and can be said to be enfolded within the 'fabric' of the honey.
If one were hypothetically able to exactly retrace one’s steps and effectively ‘un-stir’ the honey, we would find that the distributed ink blur would become a circle, then finally a spot of ink, and in this way has become ‘explicate’:
I was taught that the finished sculpture was maybe the end of the paragraph. Once a sculpture was completed it was critiqued and put back on to the scrap pile. This way of working taught me to think sculpturally rather than to think about sculpture.charles ray
please remember that we're here to make art projects. always consider the materials here sculpturally - i.e, how what you make for this class occupies visual space - meaning please account for all of the elements of your works here (from the micro-controllers to power cords to the movements your projects make) compositionally. realize that every element of your project is a mark of some kind. kinetic works move through time within visual space. in this class your work will be considered in terms of its relationships to temporal and visual space(s). use the techniques you learn here essentially. artists can do miraculous things with minimal material. work hard to create pieces that are distinguished gestures composed of authentic marks. work hard to get to the core of your interests and discoveries and develop projects that reveal those discoveries simply and clearly.
octopart (a search engine just for electronic parts)
***
Week 1
introduction to the class, questions (yours), first steps with the arduino, controlling a servo motor.
***i'll be lending you an arduino to work with tonight, please, please, please return it, along with whatever else you borrow, when you leave - my wednesday night class needs to use them, too!
***please bring a laptop to class to work on - if you don't have one, please let me know!
***i'm here to help, but require that prior to asking me to look at your code you put comments in it (see below).
intro to arduino
download and install of the development environment from here
(control) structures. A program is usually not limited to a linear sequence of instructions. During its process it may bifurcate, repeat code or take decisions. For that purpose, C/C++ provides control structures that serve to specify what has to be done by our program, when and under which circumstances. if....then....
a variable is a portion of memory alloted to store a determined value.
A function is a block of code that has a name and it has a property that it is reusable i.e. it can be executed from as many different points in a C Program as required.
btw, what does 'void' mean?
Basically it means "nothing" or "no type"
There are 3 basic ways that void is used:
1) Function argument: int myFunc(void) -- the function takes nothing.
2) Function return value: void myFunc(int) -- the function returns nothing
3) Generic data pointer: void* data; -- 'data' is a pointer to data of unknown type, and cannot be dereferenced
Note: the void in a function argument is optional in C++; int myFunc() is exactly the same as int myFunc(void). It is required for a return value.
shall we?
code example 1 ***when opening example sketches that you will make changes to, ALWAYS use Save As..:
1. examples-->basics-->blink
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
}
1. follow the link above, and copy/paste the code into a new sketch
2. upload it.
3. open the terminal window and watch what happens.
***the terminal window is a great help when working with the arduino. you can have your code send whatever you want to keep track of by using the "Serial.println(variable)" function.
4. to familiarize yourself with this functionality, add Serial.println to the Blink sketch like this:
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT); Serial.begin(9600);
}
void loop() {
digitalWrite(13, HIGH); // set the LED on Serial.println("high");
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off Serial.println("low");
delay(1000); // wait for a second
}
5. upload it
6. open the terminal window and see what you find.
ok?
code example 3: **we're about to start working with a servo motor, and to do so, we'll need to cut/strip three wires.
1. DISCONNECT YOUR ARDUINO FROM YOUR USB PORT!!!
2. wire your servo and connect it to the arduino like this --->
Servo motors have three wires:
power (RED),
ground (BLACK or BROWN), and
signal (YELLOW, ORANGE, OR WHITE).
The power wire should be connected to the 5V pin on the Arduino board.
The ground wire should be connected to a ground pin on the Arduino board.
The signal pin should be connected to a digital pin on the Arduino board.
***Note servos draw considerable power, so if you need to drive more than one or two, you'll probably need to power them from a separate supply (i.e. not the +5V pin on your Arduino). Be sure to connect the grounds of the Arduino and external power supply together.
***PAY CLOSE ATTENTION TO YOUR CONNECTIONS PRIOR TO POWERING (CONNECTING TO THE USB PORT). IF YOU ARE NOT SURE WHAT GOES WHERE PLEASE ASK. IF YOU REVERSE THE POLARITY OF THE SERVO YOU WILL FRY IT. THIS IS NOT GOOD....
FYI: how servos work -->
Here’s the one minute overview of how you control servos. Most servos rotate 180 degrees. Servos are controlled by a single digital pin. The way to tell a servo what to do is by sending them a high pulse for a certain duration. Most standard RC servos use a pulse of 1 millisecond to indicate 0 degrees of rotation and 2 milliseconds for 180 degrees. That means 90 degrees is set via a 1.5 millisecond high signal.
One problem is that our servos have minimal memory. They forget how the most recent pulse you sent them was after 50 milliseconds or so. This means just telling a servo what what position to go to once is not enough. You need to constantly remind it by sending it a series of pulses, like this:
one advantage of using an arduino is that there is a library that makes sending your servo to a specific angle/position very straightforward:
once you are positive your servo is attached to your arduino correctly, open up the arduino IDE, and navigate to the servo sweep example like so:
file-->examples-->servo-->sweep
**notice that it defaults to attaching the servo to digital pin 9, if you've attached your servo to digital pin 2, as in the photo above, you can either move the wire to pin 9, or change the code to myservo.attach(2)
now program the arduino with the sweep code.
working?
let's study the code -->
// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
now let's alter it to include some Serial.println() functions.
**remember to put the Serial.begin(9600) in the void setup () function
** then put twoSerial.println(pos) function in the appropriate place in the void loop() function
now start making changes to the code that will affect the pos variable, and watch the movement of the motor while keeping an eye on the terminal window.
ok?
next, let's change the delay(15) function so that the number 15 is contained in a variable, let's call the variable t
look carefully at the sweep example and figure out how to change the 15 to a variable called t that contains the number 15.
next add another Serial.println(t) function in the appropriate place in the code.
try your code.
working?
now change the value in t to another number, and see what happens.
***
the sweep code flows from top to bottom, and repeats forever within the void loop() function
you can alter the code by adding additional for loops with whatever angles/t's (delays) you like.
try adding two new for loops with different numbers angles/t's, and see what happens.
work with adding new for loops that create smooth transitions between pairs of for loops
add as many for loops as you like to create a sequence of movements.
take a look at the parts that came with the servo. the gears that attach to the servo are called arms and sometimes horns.
for your assignment you'll be altering the sweep code and creating a modest project using the servo, by attaching something to it, and adding for loops.
***the servos you have are not very strong - you can damage them by asking them to move something heavy - work only with light materials for this project!
remember that you want to consider how whatever you make occupies visual space. make an art piece whose content is movement, the arduino, a servo, and some additional material that is moving. the fewer lines of code and more compelling/elegant/resolved your project is the better.
***save your code (via the save as... technique) frequently. before you leave, if you are not using your own laptop, you can copy and paste your code(s) into the body of an email.
Assignment:
order an arduino, breadboard-wire kit as linked above, and download 'getting started with arduino' **you must have your arduino for next class, please ORDER TONIGHT - and pay close attention to the shipping you choose.
review the exercises we covered in class.
take a servo with you and find materials you'd like to connect to it, bring those materials to class next time!
familiarize yourselves with fritzing (ie, download it and go through the first lesson).
WEEk 2
show some dance/movement stuff
full rotation servos
another kind of servo:
full-rotation servos!
Serial.println() + Serial.print()
wondering what else can the arduino do for you? check out its entire instruction set - click on specific instructions for working code!
does a manual/pdf/tech doc for the specific motor come up?
does an Arduino Forum result come up? does anything useful come up? if not, re-try your search in the Arduino Forum.
***you want to find out what pulse length (in milliseconds) the specific servo you have responds to, can you find that from any of the sites returned in your search?
***you also want to find out what the null point for the servo is. the null point is the position where the servo will stop moving.
***to stop the servo you will, ironically, send it a pulse
and remember, just because someone made a tutorial somewhere about how to use a specific part it doesn't mean their tutorial is complete and/or fully functional. ALWAYS CHECK THE COMMENTS FOR ANY BLOG POST-TUTORIAL YOU ARE FOLLOWING. DETERMINE IF THE CODE/SCHEMATIC WORKS AND IF THE POSTER IS RESPONSIVE TO QUESTIONS. PROCEDE AT YOUR OWN RISK!!
review --> FYI: how servos work -->
Here’s the one minute overview of how you control servos. Most servos rotate 180 degrees. Servos are controlled by a single digital pin. The way to tell a servo what to do is by sending them a high pulse for a certain duration. Most standard RC servos use a pulse of 1 millisecond to indicate 0 degrees of rotation and 2 milliseconds for 180 degrees. That means 90 degrees is set via a 1.5 millisecond high signal.
With full-rotation servos the high pulse is significantly longer, but the low pulse is, usually around 20ms.
One problem is that our servos have minimal memory. They forget how the most recent pulse you sent them was after 50 milliseconds or so. This means just telling a servo what what position to go to once is not enough. You need to constantly remind it by sending it a series of pulses, like this:
so-->
using Serial.println(), (or a combination of Serial.print() + Serial.println() if you have a few pieces of information you'd like to have on the same line in the terminal window, work on getting the full rotation motors to spin clockwise, counter-clockwise, and stop, using for loops:
here's the basic code, notice you'll have to fill in some of the variables, and add comments for some of the lines -->
/*
some important information goes here....
*/
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
int delay_time = 2000; //variable for delay in servo for loop
int servo_high = ;
int servo_low = ;
void setup()
{
myservo.attach(3); // attaches the servo on pin 3 to the servo object
Serial.begin(9600);
}
do some research to discover what pulse length, in milliseconds, may work with your specific full-rotation servo
determine a range of pulse lengths you'd like to test
write them into the code above as variables
verify your code
upload your code if it verifies (aka compiles) without any errors
open the terminal/monitor window
watch carefully what the motor does, and note (i.e., write down) what pulse lengths work with your motor, remember, you want to be able to make it spin:
clockwise/fast/medium/slow
stop
counter-clockwise/fast/medium/slow
figured it out?
next, incorporate what you've learned into a movement sketch:
using for loops create a study where the motor slowly speeds up and slows down, going from clockwise to counter-clockwise to clockwise, stops, then reverses.
ok?
now start working on projects with the 180 degree and full-rotation servo.
assignment
by next week please bring in two complete movement studies/projects, one with the 180 degree, one with the full-rotation servo.
your projects should be simple/essential, but complete.
in terms of materiality it needs to be simple/essential. work with your motors so that you have a palette of movements that interest you, and you have control over, and that are essential qualities of those motors.
start experimenting with moving materials with your motors:
use monofilament wire, thin gauage copper wire, thread, zip ties, paper (card stock, cardboard, etc...), hot-glue, fabric - light materials -- speaking of which, consider the lighting of your work.... and realize that the motors make sound. the materials you use are entirely your choice.
note the elasticity and rigidity of your materials. how can you use elasticity and rigidity to augment (add dimensions of movement) to your kinetic work?
+elasticity is the quality of a material to return to its original shape after it has been stretched or compressed.
+rigidity is the quality of a material to resist being stretched or compressed.
whenever possible, try to work with materials that can contribute energy to your systems! meaning, for example, incorporating materials that have sufficient elasticity or rigidity so that they will contribute dimensions of movement in addition to what the motor can provide.
one strategy for your movement studies could be to develop a movement sketch for each motor first, then -->
working with your materials by hand, note their kinetic properties (i.e., what they do when they are moved - how do zip ties differ from paper in regard qualities of movement - elasticity/rigidity, etc. -- what is the essential difference?) -- pay close attention to how moving them affects them - including breaks them. choose the properties that you feel are essential to both the materials you are using and what you are trying to do. take risks, its the best way to learn, but please don't stress the motors....
connect your materials to your motor, and tweak both the sketch and the material construction until they present a complete gesture.
simplify your palette, experiment rigorously, and maximize your gaze.
some concepts:
Energy is a measure of how long we can sustain an output of power, or how much work we can do.
There are two kinds of energy: potential and kinetic.
Potential energy is waiting to be converted into power. Gasoline in a fuel tank, food in your stomach, a compressed spring, and a weight hanging from a tree are all examples of potential energy.
The human body is a type of energy-conversion device. It converts food into power, which can be used to do work. A car engine converts gasoline into power, which can also be used to do work. A pendulum clock is a device that uses the energy stored in hanging weights to do work. A servo motor converts electricity power.
When you lift an object higher, it gains potential energy. The higher you lift it, and the heavier it is, the more potential energy it gains. For example, if you lift a steel ball bearing 1 inch, and drop it on the roof of your car, it won't do much damage. But if you lift the ball-bearing 1000 feet and drop it on your car, it will put a dent in the roof. The same ball bearing dropped from a greater height has much more energy. So, by increasing the height of an object, you increase its potential energy.
Kinetic energy is energy of motion. Objects that are moving have kinetic energy. Kinetic energy is similar to potential energy. The more the object weighs, and the faster it is moving, the more kinetic energy it has.
***
you will make numerous discoveries, you don't need to incorporate all of them for any one assignment, just pick the one's you'd most like to work with now, and use those - you'll have plenty of time for future work to explore and present all of your discoveries and ideas.
wEEK 3
crit 1. two motion studies, one 180 servo, one continuous rotatation.
but first, headed to NYC this weekend? why not visit maker faire?
WeEk 4
A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system. -- john gall, from systemantics
using the pseudo (non-compilable) code below as your model, and Serial.println() as your output, write a functioning sketch that calls specific functions from void loop()
make a sketch that moves to different functions you create from void loop()
void setup() {
}
void loop() {
one();
}
void one() {
}
void two() {
}
void three() {
}
void four () {
}
class exercise 2a:
Serial.println() will be your only output, create four different functions that you call from void loop() randomly using switch(case):
/*
calling functions from void loop() using a switch(case)
*/
int randNumber;
void setup()
{
//whatever you need to setup + -->
randomSeed(analogRead(0));
}
void loop()
{
randNumber = random(0,4);
switch (randNumber) {
case 0:
one();
break;
case 1:
two();
break;
case 2:
three();
break;
case 3:
four();
break;
}
}
class exercise 3a:
Serial.println() will be your only output, create four different functions that you call from void loop() using a randomly sorted array!
/*
calling functions using switch and a randomly sorted array
*/
int list[] = {0,1,2,3,4,5,6,7,8,9}; //scale the elements in this array to match how many functions you have, zero counts!
int a, k;
void setup(){
Serial.begin(9600);
}
void loop(){
for (a=0; a<9; a++)
{
int r = random(a,9); // high number (in this case 9) needs to be +1 more than your functions
int temp = list[a];
list[a] = list[r];
list[r] = temp;
Serial.println(list[a]); //THIS IS YOUR VARIABLE TO PUT IN YOUR SWITCH STATEMENT
k = list[a];
switch (k){
case 0:
Serial.println("i'm zero");
break;
case 3:
Serial.println("i'm three");
break;
}
}
Serial.println(" ");
}
delay(1000);
}
working with two servos, one full rotation, one 180 degree.
copy the script below into the arduino IDE
verify it
work with one function at a time - comment out the functions you are not working with. *** remember that you'll need the closing curly brace '}' at the end of the script to close the void loop() - so close your commented functions above the bottom curly brace...
study the function
before you upload it, try to imagine what the function does
watch what it does, and before you go to the next function be sure you understand how it works.
take your time!!
if you want to tweak/hack - be sure you use Save As.
assignmentdue in two weeks, please make one construction that uses both servo motors.
the behaviors must include at least two sequential events (one motor, then the other), and at least two parallel events (both motors at the same time). remember the virtues of simple systems.
all functions must be called from void loop()
you must have some randomization, i.e., use random() somewhere in the sketch to augment the behavior of your robotic work.
***
/*
full rotation + 180 degree servo mashup
*/
#include <Servo.h>
Servo myservo_180; // create servo object to control a 180 servo
Servo myservo_FULL; // create a servo object to control a FULL rotation servo.
int i; //general purpose variable for 'for' loops below
// variables for 180 servo
int servo_180_pos = 0; // variable to store the servo position
int steps_180 = 1;
int delay_time_180 = 15;
int servo_180_high = 180;
int servo_180_low = 0;
// variables for FULL rotation servo
int servo_FULL_pos;
int steps_FULL = 1;
int delay_time_FULL = 2000; //variable for delay in servo for loop
int servo_FULL_high = 1600;
int servo_FULL_low = 1400;
int FULL_pos_1 = 1400;
int FULL_pos_2 = 1600;
void setup()
{
myservo_180.attach(9); // attaches the 180 servo on pin 9 to the servo object
myservo_FULL.attach(7); //attaches the FULL rotation servo to pin 7
Serial.begin(9600);
}
void loop()
{
// function 1, sequential: 180, then FULL rotation
for(servo_180_pos = servo_180_low; servo_180_pos < servo_180_high; servo_180_pos += steps_180) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_180_pos = servo_180_high; servo_180_pos>= servo_180_low; servo_180_pos-= steps_180) // goes from 180 degrees to 0 degrees
{
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_FULL_pos = servo_FULL_low; servo_FULL_pos <=servo_FULL_high; servo_FULL_pos+= steps_FULL){
Serial.println(servo_FULL_pos);
myservo_FULL.write(servo_FULL_pos);
}
for(servo_FULL_pos = servo_FULL_high; servo_FULL_pos >=servo_FULL_low; servo_FULL_pos-= steps_FULL){
Serial.println(servo_FULL_pos);
myservo_FULL.write(servo_FULL_pos);
}
//function 2, sequential: 180, then full, then 180, then full
for(servo_180_pos = 0; servo_180_pos < 90; servo_180_pos += steps_180) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_180_pos = 90; servo_180_pos<= 180; servo_180_pos += steps_180) // goes from 180 degrees to 0 degrees
{
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
// function 3, parallel: both at the same time, 180 sweeps, FULL rotation spins
for(servo_180_pos = servo_180_low; servo_180_pos < servo_180_high; servo_180_pos += steps_180) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
myservo_FULL.write(FULL_pos_1);
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_180_pos = servo_180_high; servo_180_pos>=servo_180_low; servo_180_pos-= steps_180) // goes from 180 degrees to 0 degrees
{
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
myservo_FULL.write(FULL_pos_2);
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
in class exercise 1b, creating custom functions and calling them from void loop().
using the script above:
make custom functions from each of the 5 functions like this:
// function 1, sequential: 180, then FULL rotation
for(servo_180_pos = servo_180_low; servo_180_pos < servo_180_high; servo_180_pos += steps_180) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_180_pos = servo_180_high; servo_180_pos>= servo_180_low; servo_180_pos-= steps_180) // goes from 180 degrees to 0 degrees
{
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_FULL_pos = servo_FULL_low; servo_FULL_pos <=servo_FULL_high; servo_FULL_pos+= steps_FULL){
Serial.println(servo_FULL_pos);
myservo_FULL.write(servo_FULL_pos);
}
for(servo_FULL_pos = servo_FULL_high; servo_FULL_pos >=servo_FULL_low; servo_FULL_pos-= steps_FULL){
Serial.println(servo_FULL_pos);
myservo_FULL.write(servo_FULL_pos);
}
becomes...
void one() {
// function 1, sequential: 180, then FULL rotation
for(servo_180_pos = servo_180_low; servo_180_pos < servo_180_high; servo_180_pos += steps_180) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_180_pos = servo_180_high; servo_180_pos>= servo_180_low; servo_180_pos-= steps_180) // goes from 180 degrees to 0 degrees
{
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_FULL_pos = servo_FULL_low; servo_FULL_pos <=servo_FULL_high; servo_FULL_pos+= steps_FULL){
Serial.println(servo_FULL_pos);
myservo_FULL.write(servo_FULL_pos);
}
for(servo_FULL_pos = servo_FULL_high; servo_FULL_pos >=servo_FULL_low; servo_FULL_pos-= steps_FULL){
Serial.println(servo_FULL_pos);
myservo_FULL.write(servo_FULL_pos);
}
}
to access your new function from void loop()
void loop(){
void one();
}
void one() {
// function 1, sequential: 180, then FULL rotation
for(servo_180_pos = servo_180_low; servo_180_pos < servo_180_high; servo_180_pos += steps_180) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_180_pos = servo_180_high; servo_180_pos>= servo_180_low; servo_180_pos-= steps_180) // goes from 180 degrees to 0 degrees
{
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_FULL_pos = servo_FULL_low; servo_FULL_pos <=servo_FULL_high; servo_FULL_pos+= steps_FULL){
Serial.println(servo_FULL_pos);
myservo_FULL.write(servo_FULL_pos);
}
for(servo_FULL_pos = servo_FULL_high; servo_FULL_pos >=servo_FULL_low; servo_FULL_pos-= steps_FULL){
Serial.println(servo_FULL_pos);
myservo_FULL.write(servo_FULL_pos);
}
}
OK?
once you have made your custom functions verify and then upload and test the sketch.
in class exercise 2b, using random().
using function 3 from the script above:
use random () to affect the movement of the continuos rotation servo like this:
***declare int randPos; at the top of your sketch
// function 3, parallel: both at the same time, 180 sweeps, FULL rotation spins randPos = random(1400, 1500);
for(servo_180_pos = servo_180_low; servo_180_pos < servo_180_high; servo_180_pos += steps_180) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
myservo_FULL.write(randPos);
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
randPos = random(1500, 1600);
for(servo_180_pos = servo_180_high; servo_180_pos>=servo_180_low; servo_180_pos-= steps_180) // goes from 180 degrees to 0 degrees
{
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
myservo_FULL.write(randPos);
delay(delay_time_180); // waits 15ms for the servo to reach the position
} randPos = random(45);
once you have made your custom functions verify and then upload and test the sketch.
class exercise 3b, find two other places in your sketch to use random()
class exercise 4b, randomize the order the your functions are called from void loop()
wwEk 5
review/workshop
variable review -->
a variable is something that changes.
in the world of code>>
A variable is a place to store a piece of information. Just as you might store a friend's favorite artist in your own memory, you can store this information in a computer's memory. Variables are your way of accessing your computer's memory.
Of course, your memory changes over time. Your friend sees a lot of art, and her tastes change as her knowledge grows, and your friend's new favorite artist will replace the former one in your memory. Over time, as you acquire new friends, your memory will keep changing to store different pieces of information. Likewise, a computer's memory can change over time, if you tell it to. Since variables are your access point to your computer's memory, it makes sense that you'd be able to change the information in a computer's memory; otherwise, they wouldn't be called variables (they'd be called statics).
Why should you care about variables? Variables are the essence of any computer program! Without variables, computers would be horrifically inefficient. Imagine a program which asks the user for two numbers and adds them together, and prints the result.
// AddTwoNumbers
Enter the first number: 2
Enter the second number: 5
The sum of 2 and 5 is 7.
//
Sounds simple, right? But let's do a little role-playing to see what the computer has to do to execute this program. Instead of this interaction between a person and a computer, let's imagine the same kind of conversation between two people, Sandra and Luis.
Sandra: Hey Luis, I just learned how to add two numbers together.
Luis: Cool!
Sandra: Give me the first number.
Luis: 2.
Sandra: Ok, and give me the second number.
Luis: 5.
Sandra: Ok, here's the answer: 2 + 5 = 7.
Luis: awesome!
After Luis says "2", Sandra has to store that number in her memory somewhere. It may be stored in short-term memory, but he has to store it somewhere before Luis gives her the second number. Even if Luis were to give her two numbers in the same sentence, Sandra would have to store the numbers somewhere in his memory to add them together.
In the sample program described above, the computer would most likely store "2" in a variable, then store "5" in a variable, and then calculate the sum by calculating the sum of the numbers store in the two variables.
Although there are similarities between a person's memory and a computer's memory, there are some pretty big differences. In C, the language Arduino is based in, you need to grab a little piece of the computer's memory before you can use it. In other words, you have to tell the computer that you're planning to store a number in a variable before you can actually do it. This is called declaring a variable. To declare a variable, you need to know what kind of information it will store (i.e., will it store a number, or a text-string, or something else) and how you plan to refer to the variable (i.e., the variable's name). C imposes fairly strict rules on how you can name your variables:
variable names must begin with a letter
variable names are "case-sensitive" (i.e., the variable "myNumber" is different from the variable "MYNUMBER" which is different from the variable "mYnUmBeR")
variable names can't have spaces
variable names can't have special characters (typographic symbols)
What can you name your variables? In general, variable names can be composed of letters, numbers, and underscores (_). However, C reserves certain keywords which have special meaning to the language, and you are not allowed to use any of these keywords as variables names. Some examples of C keywords are int, for, else, and class. You can, however, use keywords in the middle of a variable name, such as "foreign" or "classical".
even MORe random
void one() {
// function 1, sequential: 180, then FULL rotation
steps_180 = random(1,10); // what effect will this have?
for(servo_180_pos = servo_180_low; servo_180_pos < servo_180_high; servo_180_pos += steps_180) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
steps_180 = random(1,10); // what effect will this have?
for(servo_180_pos = servo_180_high; servo_180_pos>= servo_180_low; servo_180_pos-= steps_180) // goes from 180 degrees to 0 degrees
{
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
steps_FULL = random(1,10); // what effect will this have?
The human body, like anything else that is large enough and slow enough, is bound by the laws of Newtonian mechanics. Our research is centerred on understanding of how humans walk from a Newtonian mechanics point of view. If we can gain better insight into how humans walk, perhaps we could improve prosthetics for the gait-impaired, help correct neuro-muscular deficiencies, or build better two-legged walking robots. Our approach, which picks up on the ideas and inventions of Tad McGeer, is to focus on what aspects of coordination can be largely explained by mechanics.
Our first of two near duplicates of one of McGeer's machines is shown walkingdownhill and to the left in this photo. The machine is meant to vaguely resemble a set of human legs in two dimensions. This so-called passive dynamic walker has no actuation except gravity, and no control system, except for mechanical knee stops that prevent the shanks from hyperextending with respect to the thighs. Inner and outer legs are paired to constrain it from falling over sideways, but it can still fall forward or backward or buckle at the knees. Curiously enough, as Tad McGeer first showed, this robot and others like it are capable of stable, human-looking walking. This visual appearance alone suggests that passive dynamic effects play a big role in the mechanics of human gait, that Nature takes major advantage of these passive stability and efficiency mechanisms in its designs. -- from passive dynamics at cornell university
**An actuator is a mechanical device for moving or controlling a mechanism or system. It is operated by a source of energy.
PS. don't like variables? enter numbers instead -- for loops with number and not variables. simple example of loop() with functions
i.e. ----->
void one() {
// function 1, sequential: 180, then FULL rotation
for(servo_180_pos = 0; servo_180_pos < 180; servo_180_pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
for(servo_180_pos = 180; servo_180_pos>= 0; servo_180_pos-= 1) // goes from 180 degrees to 0 degrees
{
Serial.println(servo_180_pos);
myservo_180.write(servo_180_pos); // tell servo to go to position in variable 'pos'
delay(delay_time_180); // waits 15ms for the servo to reach the position
}
runaway servo syndrome? is your full rotation servo moving when you don't want it to??
servo_full.write(STOP_VALUE) //apply liberally
assignmentdue next week, please make one construction that uses both servo motors.
the behaviors must include at least two sequential events (one motor, then the other), and at least two parallel events (both motors at the same time). remember the virtues of simple systems.
all functions must be called from void loop()
you must have some randomization, i.e., use random() somewhere in the sketch to augment the behavior of your robotic work.
eWEK 6
crit II
Wk 7
serial.print -- DEBUG toggle trick:
int DEBUG = 0 ; // DEBUG counter; if set to 1, will write values back via serial
void setup(){
if (DEBUG) { // If we want to see values for debugging...
Serial.begin(9600); // ...set up the serial ouput
}
the LAC can handle: 5–24 VDC, 4 Amps peak current at 10% duty cycle
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
int randPos;
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop()
{
randPos = random(0,10);
switch(randPos){
case 0:
pos = 1100;
break;
case 1:
pos = 1200;
break;
case 2:
pos = 1300;
break;
case 3:
pos = 1400;
break;
case 4:
pos = 1500;
break;
case 5:
pos = 1600;
break;
case 6:
pos = 1700;
break;
case 7:
pos = 1800;
break;
case 8:
pos = 1900;
break;
case 9:
pos = 2000;
break;
myservo.writeMicroseconds(pos);
delay(9000);
}
}
Stepper Motors
Stepper motors operate differently from DC brush motors, which rotate when voltage is applied to their terminals. Stepper motors, on the other hand, effectively have multiple "toothed" electromagnets arranged around a central gear-shaped piece of iron. The electromagnets are energized by an external control circuit, such as an arduino. To make the motor shaft turn, first, one electromagnet is given power, which makes the gear's teeth magnetically attracted to the electromagnet's teeth. When the gear's teeth are aligned to the first electromagnet, they are slightly offset from the next electromagnet. So when the next electromagnet is turned on and the first is turned off, the gear rotates slightly to align with the next one, and from there the process is repeated. Each of those slight rotations is called a "step", with an integer number of steps making a full rotation. In that way, the motor can be turned by a precise angle.
Stepper motors are constant power devices.
As motor speed increases, torque decreases. (most motors exhibit maximum torque when stationary, however the torque of a motor when stationary (holding torque) defines the ability of the motor to maintain a desired position while under external load).
The torque curve may be extended by using current limiting drivers and increasing the driving voltage (sometimes referred to as a 'chopper' circuit; there are several off the shelf driver chips capable of doing this in a simple manner).
This vibration can become very bad at some speeds and can cause the motor to lose torque or lose direction. This is because the rotor is being held in a magnetic field which behaves like a spring. On each step the rotor overshoots and bounces back and forth, "ringing" at its resonant frequency. If the stepping frequency matches the resonant frequency then the ringing increases and the motor comes out of synchronism, resulting in positional error or a change in direction. At worst there is a total loss of control and holding torque so the motor is easily overcome by the load and spins almost freely.
The effect can be mitigated by accelerating quickly through the problem speeds range, physically damping (frictional damping) the system, or using a micro-stepping driver.
Motors with a greater number of phases also exhibit smoother operation than those with fewer phases (this can also be achieved through the use of a micro-stepping driver)
Stepper Motor Wiring
In general, 2-phase stepper motors can have 4, 6 or 8-wire leads, not including any (optional) encoder lines. Some stepper motors have a motor case ground that can be tied to the ground of the system. It is usually a black wire, and it will add one additional wire to the overall count (4 coil wires + 1 casing ground = 5 wires total).
4 Wire Motors: Approach 1 (using a multimeter)
Each of the two phases should have the same resistance when measured with a multimeter. When measuring the resistance across one wire from each of the two phases, the resistance should be infinite because the circuit is open. Locate the two pairs of wires that represent the two phases, and both pairs of wires will have similar internal resistance.
Connect each phase to the amplifier and ignore the polarity (+ / -), for now. You have a 50% chance of guessing right.
Send a command to move the motor. If the motor rotates in the wrong direction, then switch either phase A and A- or B and B- (effectively reversing directions).
4 Wire Motor: Approach 2 (w/o a multimeter)
Connect the four coil wires to the amplifier in any arbitrary pattern. Send a command to move the motor.
If the motor moves erratically or not at all, then switch one wire from phase A with one wire from phase B.
If the motor is rotating in the wrong direction, then switch either phase A and A- or B and B- (effectively reversing directions)
. 6 Wire Motors
If you have six coil wires, then each phase has a center tap wire.
The center tap wire should have half the internal resistance of the full phase. The easiest option is to use a multimeter to find the two pairs of wires that have the maximum resistance.
Connect each phase to the amplifier, and ignore the polarity (+ / -) for now. You have a 50% chance of guessing right. The motor should rotate, and if it is in the opposite direction, then switch either phase A and A- or B and B- (effectively reversing directions).
8 Wire Motors:
If you have eight coil wires, then it is highly recommended you find the exact pinout for the motor.
The eight wires represent four pairs of wires, and each pair has the same resistance. It is not easy to find what two pairs represent phase A and phase B without dismantling the motor.
**i'll be lending you one, please return it at the end of the semester
if you'd like to purchase one of your own, please get the one linked above
the stepper motor will require its own power supply
how to wire the stepper
the power supply must share a ground ("gnd", "0V") connection with the arduino and the motor driver shield in order for them to communicate.
DO NOT CONNECT THE POSITIVE OUTPUT, (RED WIRE), OF THE STEPPER POWER SUPPLY TO THE ARDUINO!!!
we'll be using a jack to plug the stepper power supply into the bread board, and then power the motor control shield from the breadboard.
Steps (that's a pun, get it?)
connect your motor shield to your arduino
connect your stepper motor to your motor shield's Motor Out, Coil A/Motor Out, Coil B screw terminals
wire your jack to your breadboard
connect the POS (+) wire from the power supply from the jack to a red bus line on your breadboard
connect the red bus line to the "8-30v" screw terminal on your motor shield
connect the GND (-,0) wire from the power supply from the jack to a blue bus line on your breadboard
connect the blue bus line to your motor shield's "GND" screw terminal (next to the "8-30v" input).
almost ready.....
there are three variables that control the stepper:
DIR (direction) this number is positive (forward/clockwise), or negative (backward/counter-clockwise)
the integer that is stored in DIR determines the step size of the clockwise or counter-clockwise movements of the motor.
***all stepper motors make full rotations in a specific number of steps, our motor makes a full rotation in 200 steps.
PWM determines the torque, or power of the motor, PWM must be between 5 and 200, and is changed in increments of 5 (we won't notice changes in increments less than 5).
RPM determines the speed of the motor, RPM, for this motor, should be between 1 and 200, and is changed in increments of 1.
***you'll notice that you'll have to adjust the PWM as you adjust the RPM and vice versa. use the sketch above to determine combinations of PWM and RPM that work.
USE YOUR EARS AS WELL AS EYES TO DETERMINE HOW YOUR MOTOR IS RESPONDING TO YOUR CODE. IF THE MOTOR IS WHINING, GRINDING, TWITCHING OR STALLING TRY ALTERING THE PWM/RPM COMBINATIONS.
try this -->
stepper working sketch
#include <Stepper.h>
/*
a simple sketch that moves the stepper in precise steps, speed, and torque
*/
// Define how many steps there are in 1 revolution of your motor
#define STEPS_PER_REVOLUTION 200
/**********************************************************/
/* YOU SHOULDN'T HAVE TO CHANGE ANYTHING BETWEEN THIS POINT and VOID SETUP()*/
/**********************************************************/
// Change from divide-by-64 prescale on Timer 2 to divide by 8 to get
// 8-times faster PWM frequency (976 Hz --> 7.8 kHz). This should prevent
// overcurrent conditions for steppers with high voltages and low inductance.
TCCR2B = _BV(CS21);
// Now enable PWM and start motion
analogWrite(EN1_PIN, PWM);
analogWrite(EN2_PIN, PWM);
stepper.setSpeed(RPM);
}
/**********************************************************/
/* YOU CAN MAKE CHANGES IN VOID LOOP()*/
/**********************************************************/
#include <Stepper.h>
/* This Rugged Motor Shield application demonstrates keyboard control
* of a stepper motor. Assumptions:
*
* - stepper motor connected to the 2 phases
* - 8V-30V supply connected to Vin (optional, else Arduino Vin is used)
* - Vin jumper is cut (J21) (only required if Vin>15V)
* - FAULT1 and FAULT2 jumpers (J10/J14) installed (optional)
* - LED jumpers (J15, J16, J6, J7) installed (optional)
*
* The behavior is as follows:
*
* - The 'f' key sets forward motion
* - The 'b' key sets backwards motion
* - The 'a' key accelerates rotational speed
* - The 'd' key decelerates rotation speed
* - The 'o' key increases motor power (PWM higher duty cycle)
* - The 'm' key decreases motor power (PWM lower duty cycle)
*
* This software is licensed under the GNU General Public License (GPL) Version
* 3 or later. This license is described at
* http://www.gnu.org/licenses/gpl.html
*
* Application Version 1.0 -- October 2010 Rugged Circuits LLC
* http://www.ruggedcircuits.com
*/
// Define how many steps there are in 1 revolution of your motor
#define STEPS_PER_REVOLUTION 200
/**********************************************************/
/* YOU SHOULDN'T HAVE TO CHANGE ANYTHING BELOW THIS POINT */
/**********************************************************/
// General-purpose LED's, active high
#define LED0_PIN 9 // For motor A
#define LED1_PIN 10 // For motor A
#define LED2_PIN 16 // For motor B
#define LED3_PIN 17 // For motor B
// Change from divide-by-64 prescale on Timer 2 to divide by 8 to get
// 8-times faster PWM frequency (976 Hz --> 7.8 kHz). This should prevent
// overcurrent conditions for steppers with high voltages and low inductance.
TCCR2B = _BV(CS21);
// Now enable PWM and start motion
analogWrite(EN1_PIN, PWM);
analogWrite(EN2_PIN, PWM);
stepper.setSpeed(RPM);
}
void printHelp()
{
Serial.println(
"f - forward motion\n"
"b - backwards motion\n"
"a - faster\n"
"d - slower\n"
"o - more power\n"
"m - less power\n"
);
}
void loop()
{
if (Serial.available()) {
switch (Serial.read()) {
case 'f': case 'F': DIR = 1;
Serial.println("FORWARD");
break;
case 'b': case 'B': DIR =-1;
Serial.println("BACKWARD");
break;
case 'o': case 'O':
if (PWM <= 250) PWM += 5;
Serial.print("PWM="); Serial.println(PWM);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
break;
case 'm': case 'M':
if (PWM >= 5) PWM -= 5;
Serial.print("PWM="); Serial.println(PWM);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
break;
case 'a': case 'A':
RPM++;
Serial.print("RPM="); Serial.println(RPM);
stepper.setSpeed(RPM);
break;
case 'd': case 'D':
if (RPM > 1) RPM--;
Serial.print("RPM="); Serial.println(RPM);
stepper.setSpeed(RPM);
break;
case 'h': case 'H':
printHelp();
break;
default:
Serial.println("Unknown command");
break;
}
}
// This is a busy-wait loop until the inter-step time passes
stepper.step(DIR);
}
upload the study sketch above, and, well, study it... look carefully and take notes about PWM/RPM combinations that work, and don't work. DON'T MODIFY THIS SKETCH, KEEP IT AS A REFERENCE
class exercise #1:
vary the working sketch above by creating a sequence of at least 10 different movements, from large to small. CONFINE YOUR WORK TO THE VOID LOOP()
class exercise #2:
incorporate delay (some_integer) to add complexity and character to your movements
the less precise stepper...
what if, as in the script above, you want to control the speed, torque and direction of the motor but you are not concerned with precise positioning (in other words, what if you want to use your stepper as a reversible dc motor)?
DIR = 1;
for (int i = 0; i <=200; i +=1) {
stepper.step(DIR);
}
in class exercise #3:
make the motor spin clockwise, then counter-clockwise using for loops
PWM/RPM
in class exercise #4:
using the sketch above as a guide, you can add PWM control to your stepper by adding these lines of code:
DIR = -1; //counter clockwise rotation
PWM = 50; //
for (int i = 0; i<=200; i+=1){
stepper.step(-1);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM); //torque
}
in class exercise #5:
using the sketch above as a guide, you can add RPM control to your stepper by adding these lines of code:
***you'll notice that you'll have to adjust the PWM as you adjust the RPM and vice versa. use the sketch above to determine combinations of PWM and RPM that work.
DIR = -1; //counter clockwise rotation
PWM = 100; //
RPM = 100; //speed of the motor is now 100 rotations per minute
for (int i = 0; i<=100; i+=1){
stepper.step(DIR);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM); //torque
stepper.setSpeed(RPM);
}
how do i attach things to the shaft of the stepper?
for temporary projects tape/zip ties/press fitting cardboard
for more sturdy connections
press fitting heavier materials like plastic or wood
clamping hubs ***these require a hex key**/shaft collars/clamp collars
to use the more permanent solutions you need to know the 'bore' (diameter) of the motor shaft. the motor datasheet will tell you that.
assignment due in two weeks (no class next week/fall break)
review the servo material from the beginning of the semester. please be sure that you understand how the code affects the motors.
familiarize yourselves with the stepper scripts above.
create a stepper project/study along the lines of your previous projects.privilege the movement of the motor, not what the motor is controlling.
case 'f': case 'F':
pos2 = random(1000,1840);
Serial.print("POS2="); Serial.println(pos2);
linear2.writeMicroseconds(pos2);
break;
but, why? when you're developing your projects the more direct access/control you have over your functions/behaviors/actions the better. by using key commands from the serial monitor to call different functions within your evolving project you can study them in greater detail, when you want to, without having to constantly stop, edit, and upload your sketches. see?
in class exercise #1. add key commands for different functions in the study you created for today.
adding servo control to your motor shield
Basic Control
The following Arduino pins are used by default to control the two motor outputs.
Pin
Function
D3
ENABLE1
D12
DIRECTION1
D11
ENABLE2
D13
DIRECTION2
The pin assignments can also be changed with some simple board modifications.
ENABLE1 and ENABLE2 can be driven with steady logic level signals (high to enable motor power, low to disable it) or driven by PWM outputs to vary the average motor current smoothly from no power to full power.
The DIRECTION1 and DIRECTION2 signals control the direction of the flow of current in each motor output, hence the direction of rotation for brush DC motors.
For stepper motors, these two direction outputs must be pulsed in the proper sequence to effect forward or reverse rotation. The Stepper library handles this logic for you.
An LED is also connected to pin D9. Three other LED’s are available (on pins D10, D16, and D17) but require jumpers to be shorted before they can be used.
using the above stepper_study sketch, develop a new sketch where you are calling your functions from the Serial Terminal, via key commands
according to the table above, the motorshield is using Digital pins 3, 11, 12,13. according to the schematic, it is using quite a few more pins.
the pins that we will/can use to connect our servos are analog pins 4-5 (see below). for our servos we need Digital pins, so what to do?
analog pins on the arduino can be used as digital pins. the trick is to find out what their digital pin numbers are:
Analog Pin #
Digital Pin #
A0
D14
A1
D15
A2
D16
A3
D17
A4
D18
A5
D19
locate those pins on your motorshield, and note where they are.
what this means is that you can attach your servos to any Digital pins 18, 19, which are located (image above) on the analog bank of pins, #4 and #5.
what this also means is that when you are using the servo.attach(x) function with the motor shield, x cannot ever be a number other than 18 or 19.
as usual, your servos will need power (red wire), and ground (black wire), so use your breadboards to create power and ground bus lines for your servos.
power (+5 v only for servos) and ground is also available on the motor shield.
to access the additional digital pins, power, and ground to connect our servos we'll have to make four additions to the motor shield. i'll do these during dinner.
before we do the next exercises, please connect your servos to your motor shield, and test them via a sketch to make sure they are working. to make things easier, please connect your servos' control pins (white wire) to pins 18 and 19 of your arduino/motor shield
ok?
putting them all together:
attach your motors, and upload the script below--> it should enable you to sequentially move your stepper and 180 degree servo (attached to digital pin 19). one function will move both the stepper and your 180 degree servo.
#include <Stepper.h>
#include <Servo.h>
Servo myservo;
int pos = 0;
// Define how many steps there are in 1 revolution of your motor
#define STEPS_PER_REVOLUTION 200
/**********************************************************/
/* YOU SHOULDN'T HAVE TO CHANGE ANYTHING BETWEEN THIS POINT */
/**********************************************************/
// General-purpose LED's, active high
#define LED0_PIN 9 // For motor A
#define LED1_PIN 10 // For motor A
#define LED2_PIN 16 // For motor B
#define LED3_PIN 17 // For motor B
// Change from divide-by-64 prescale on Timer 2 to divide by 8 to get
// 8-times faster PWM frequency (976 Hz --> 7.8 kHz). This should prevent
// overcurrent conditions for steppers with high voltages and low inductance.
TCCR2B = _BV(CS21);
// Now enable PWM and start motion
analogWrite(EN1_PIN, PWM);
analogWrite(EN2_PIN, PWM);
stepper.setSpeed(RPM);
}
/**********************************************************/
/* AND THIS POINT */
/**********************************************************/
void loop()
{
control();
}
void control(){
if (Serial.available()) {
switch (Serial.read()) {
case 'f': case 'F': DIR = 1;
Serial.println("FORWARD");
break;
case 'b': case 'B': DIR =-1;
Serial.println("BACKWARD");
break;
case 'o': case 'O':
if (PWM <= 250) PWM += 5;
Serial.print("PWM="); Serial.println(PWM);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
break;
case 'm': case 'M':
if (PWM >= 150) PWM -= 5;
Serial.print("PWM="); Serial.println(PWM);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
break;
case 'a': case 'A':
RPM++;
Serial.print("RPM="); Serial.println(RPM);
stepper.setSpeed(RPM);
break;
case 'd': case 'D':
if (RPM > 45) RPM--;
Serial.print("RPM="); Serial.println(RPM);
stepper.setSpeed(RPM);
break;
case 'h': case 'H':
printHelp();
break;
case 'i': case 'I':
Serial.println("sweep w/ stepper");
sweep();
break;
case 'j': case 'J':
Serial.println("sweep w/o stepper");
sweep_no_step();
break;
case 'k': case 'K':
Serial.println("stawp it");
stop_it();
break;
default:
Serial.println("Unknown command");
printHelp();
break;
}
}
// This is a busy-wait loop until the inter-step time passes
stepper.step(DIR);
}
void sweep()
{
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
stepper.setSpeed(RPM);
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
stepper.step(DIR);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
stepper.step(DIR);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
void sweep_no_step()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
void printHelp()
{
Serial.println(
"f - forward motion\n"
"b - backwards motion\n"
"a - faster\n"
"d - slower\n"
"o - more power\n"
"m - less power\n"
"i - 180 servo sweep w/ stepper\n"
"j - 180 servo sweep w/o stepper\n"
);
}
void stop_it(){
delay(10000);
}
in class exercise #1:
code a brief study in sequential movement between the 180 degree servo, the stepper, and no movement. in order to do this you'll have to add some functions for both.
control your sequence via keyboard commands (as in the script above).
think carefully about your sequences! observe the relationship between them.
when you have a sequence you are confident about, call me over to take a look.
in class exercise #2:
add your full rotation servo to your motor shield.
create three functions that use it:
one where it is spinning on its own
one where it is spinning with the stepper
one where it is spinning with the 180
as in the sketches above, access your functions via keyboard commands
assignment
create one sketch with four different movements for each motor (you can add one movement per motor to the sketch you wrote in class tonight). write your sketch so that each motor movement is triggered by a keyboard command.
please be prepared to perform your sequence in class.
attach only the most simple materials to your motors. focus on the qualities of the motors and the movements/sounds they make. do not attach anything to your motors that is not essential to your sequence.
find one short online video clip that shows a movement that you find compelling. please email me your clip by monday night so that i'll have time to put them on this syllabus.
next week we'll begin class by looking at your clips - i'll ask each of you to briefly mention what you find compelling about the clip you submitted.
How do gears work?
In the simplest terms a gear is a way to generate speed or power or change the direction of power. Most gears are wheels with teeth at their rims, and are mounted on shafts, most often connected to motors. When two gears are meshing (connected) they are called a transmission or gear train. gear trains have drivers and followers. for our purposes, the gear that is connected to the shaft of the motor, and turns the other one is known as driver, and the gear that gets turned by the driver is referred to as follower.
What do Gears do?
Gears can be used to do the following things -
Increase or Decrease Speed
By connecting two gears together, Gear A with 10 teeth and Gear B with 5 teeth. Gear B will have to turn around much faster to keep up with gear A, however it does so with half as much turning force. The fact that B is turning faster than A is down to the gear ratio.
Increase Force
To increase the force of gears, the second gear in a pair of gears will have fewer teeth than our first gear, it will turn slower but will do so with more force.
Change Direction
When two gears are meshing together, the second gear always turns in the opposite direction to the first gear. So if Gear A is turning clockwise, Gear B will turn anti-clockwise. If you had three gears meshing together A and B would be turning clockwise, whilst B would be turning anti-clockwise. The middle gear in this sequence is known as an idler gear and is used when you want to keep the input and output shafts turning in the same direction.
A simple rule applies. Low gear ratio = more speed = less force i.e, the driver is larger than the follower
High gear ratio= less speed = more force. i.e, the driver is smaller than the follower.
WHAT IS A GEAR RATIO???
A gear ratio defines the relationship between multiple gears.
For example, if our motor is attached to a gear with 60 teeth and this gear is then attached to a gear with 20 teeth that drives a wheel, our gear ratio is 60:20, or more accurately 3:1
If you do not want to count a gears teeth (or if they do not exist), gear ratio's can also be determined by measuring the distance between the center of each gear to the point of contact.
For example, if our motor is attached to a gear with a 1" diameter and this gear is connected to a gear with a 2" diameter attached to a wheel,
From the center to edge of our input gear is 0.5"
From the center to edge of our output gear is 1"
Our ratio is 1/0.5 or more accurately 2:1
How does a gear ratio affect speed?
The gear ratio tells us how fast one gear is rotating when compared to another.
If our input gear (10 teeth) is rotating at 5 rpms , and it is connected to our output gear (50 teeth), our output gear will rotate at 1 rpms.
Why?
Our gear ratio is 50:10... or 5:1
If our small gear rotates 1x, our large gear only rotates 1/5. It takes 5 rotations of our small gear to = 1 rotation of our large gear. Thus our large gear is rotating at 1/5 the speed = 1rmp.
What if our gear ratio where 1:3 ?
In this case our input gear is 3x larger as large as our output gear.
If our input gear were rotating at 20rmps.... each rotation, would result in 3 rotations of our output gear. Our output would be 60rpms.
How does gear ratio affect Torque?
First....What is torque?:
Torque is a twisting force- (it doesn't do any 'work' itself- it is simple an application of energy).
Work (or 'stuff') happens, when torque is applied and movement occurs.
"Torque is a force that tends to rotate or turn things. You generate a torque any time you apply a force using a wrench. Tightening the lug nuts on your wheels is a good example. When you use a wrench, you apply a force to the handle. This force creates a torque on the lug nut, which tends to turn the lug nut.
English units of torque are pound-inches or pound-feet; the SI unit is the Newton-meter. Notice that the torque units contain a distance and a force. To calculate the torque, you just multiply the force by the distance from the center. In the case of lug nuts, if the wrench is a foot long, and you put 200 pounds of force on it, you are generating 200 pound-feet of torque. If you use a two-foot wrench, you only need to put 100 pounds of force on it to generate the same torque." (howstuffworks.com)
In summary: Torque equals Force multiplied by Distance
How does gear ratio affect Torque?
Simply put, torque at work (such as at a wheel) is your motor's torque times your gear ratio.
Motor Torque x gear ratio = torque at the wheel
Lets say we have a 10rmps motor that is capable of 5 oz Torque (we know this from our motor spec.)
Lets say we have 2 gears. Our input gear (attached to our motor) has 10 teeth Our output gear has 50 teeth
connecting the gear assemblies to your motor shield
***for this project do not connect your external power supply to your motor shield!
here's the reversible, dc motor code:
#include <Stepper.h>
/* This Rugged Motor Shield application demonstrates basic DC motor control.
*
* basic setup:
*
* - two DC motors connected to the 2 motor outputs
* - Arduino Vin is used, NOT the 8V-30V supply/external power
*
* The behavior is as follows:
*
* - Motor 1 spins forward for 1 second
* - Motor 1 stops for 1 second
* - Motor 1 spins in reverse for 1 second
* - Motor 1 stops for 1 second
* - Motor 2 spins forward for 1 second
* - Motor 2 stops for 1 second
* - Motor 2 spins in reverse for 1 second
* - Motor 2 stops for 1 second
*
* The above motions repeat in an endless loop
*
*/
// Direction outputs
#define DIR1_PIN 12
#define DIR2_PIN 13
void setup()
{
// Configure all outputs off for now
pinMode(EN1_PIN, OUTPUT); digitalWrite(EN1_PIN, LOW);
pinMode(EN2_PIN, OUTPUT); digitalWrite(EN2_PIN, LOW);
pinMode(DIR1_PIN, OUTPUT); digitalWrite(DIR1_PIN, LOW);
pinMode(DIR2_PIN, OUTPUT); digitalWrite(DIR2_PIN, LOW);
// Both motors off for now
analogWrite(EN1_PIN, 0);
analogWrite(EN2_PIN, 0);
}
void loop()
{
digitalWrite(DIR1_PIN, LOW); // Set Motor 1 forward direction
analogWrite(EN1_PIN, 255); // Motor 1 on in forward direction
delay(1000);
analogWrite(EN1_PIN, 0); // Motor 1 off
delay(1000);
digitalWrite(DIR1_PIN, HIGH); // Set Motor 1 reverse direction
analogWrite(EN1_PIN, 255); // Motor 1 on in reverse direction
delay(1000);
analogWrite(EN1_PIN, 0); // Motor 1 off
delay(1000);
digitalWrite(DIR2_PIN, LOW); // Set Motor 2 forward direction
analogWrite(EN2_PIN, 255); // Motor 2 on in forward direction
delay(1000);
analogWrite(EN2_PIN, 0); // Motor 2 off
delay(1000);
digitalWrite(DIR2_PIN, HIGH); // Set Motor 2 reverse direction
analogWrite(EN2_PIN, 255); // Motor 2 on in reverse direction
delay(1000);
analogWrite(EN2_PIN, 0); // Motor 2 off
delay(1000);
}
in clase exercise #1
can you find a way to change the speed of the motor?
final projects will be presented the last day of class
after dinner next week, our remaining three 1/2 classes will be final project workshops
the final project must include a stepper motor and two other motors, either two servos (180 and 360) or one servo (either 180 or 360), and one reversible dc motor and gear assembly.
the sequence of movements you create must have at least four programmed changes.
your final project code must be submitted by the end of our last class. your final project code must contain comments including your name, title of the project and brief description of what it does, i.e.,
/*
final project for IS 335, fall, '11 by xyz. this project controls one stepper motor and two servos. the stepper motor is attached to…. and the servos are attached to…
*/
assignment each gear assembly team will present a brief description on their respective gear assembly, including what it does/how it works.
meaning: do some research into your respective assemblies and share what you find with us next time. basic requirements:
why would one choose to use the gear train you have?
demonstrate what it can do.
***please be sure to bring your materials so that you can work on your projects in class!!
for your final project must last at least 2 minutes - meaning that the sequence of movements must take at least two minutes to complete one cycle.
wekee 10
electron tunneling, another kind of movement, pay close attention to what he says starting at 2:38
how to add a solenoid and simple, geared dc motor to your motor shield
in class exercise #1:
servo/programmable dc/solenoid
connect your programmable dc to the motor control screw terminal #1 on the motorshield
connect your servo to pin 19
connect your solenoid to the motor control screw terminal #2 on the motorshield
carefully wire your servo so that it is getting 5v dc
try this:
#include <Stepper.h>
#include <Servo.h>
Servo myservo;
int pos = 0;
/* This Rugged Motor Shield application demonstrates basic DC motor control.
*
* basic setup:
*
* - two DC motors connected to the 2 motor outputs
*
* The behavior is as follows:
*
* - Motor 1 spins forward for 1 second
* - Motor 1 stops for 1 second
* - Motor 1 spins in reverse for 1 second
* - Motor 1 stops for 1 second
* - Motor 2 (solenoid) fires
* - Servo on pin 19 sweeps
*
* The above motions repeat in an endless loop
*
*/
analogWrite(EN2_PIN, 0); // solenoid off
delay(1000);
///180 DEG SERVO
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
final project revision: use AT LEAST three motors, two of them can on/off (dc or solenoid), one of them must be programmed to do something other than on/off, i.e., if you want to use the reversible dc motor as one of your programmed motors you must make it change speeds and direction a few times in your project.
some possible motor combinations:
stepper + 2 more motors
stepper/two servos
stepper/servo/dc (on/off)
stepper/servo/solenoid
stepper/solenoid/dc(on/off)
servo + 2 more motors
either servo + solenoid or dc, both just programmed to be on/off
programmed dc + 2 motors
**you'll probably end up having two programmed motors in this set
if you want to use a programmed dc motor (controlling the speed, direction) you can't use a stepper.
***for future reference, how not to fry your arduino***
inductance
the output voltage of an arduino is 5vdc. if you have a motor, like a reversible dc motor that operates at that voltage you might decide to plug the ground of the motor into the ground of the arduino, and the + of the motor into one of the digital outputs of the arduino and turn the motor on/off by powering the digital output pin.
please don't.
Current flowing through a coil (motors have coils inside them) creates a magnetic field that collapses suddenly when the current is switched off. The sudden collapse of the magnetic field induces a brief high voltage across the coil that is very likely to damage transistors and ICs. using a protection diode allows the induced voltage to drive a brief current through the coil (and diode) so the magnetic field dies away quickly rather than instantly. This prevents the induced voltage becoming high enough to cause damage to transistors and ICs. arduinos have transistors inside of them.
write some code that controls the speed and direction of the dc motor, and also has functions that control the servo and solenoid.
trigger your functions via keyboard commands
assignment
simple project that controls the reversible dc motor (change its speed and rotation), one servo, and one solenoid via keyboard commands + by calling functions from the void loop().
you may be able to have small (5"x5"x5") objects for your final project printed in our new fab lab.
in order to do this, design your object in google sketchup, install one of the .stl file exporters below, export your file as a .stl file and email it to me.
COMBINING STEPPERS/SERVOS/DC/SOLENOID part ii, Transistors as switches
transistors/diodes
we'll be using a TIP-120 as a switch--->
for the solenoid, +V = 12v dc
for the reversible dc motor, +V = 5v dc
the control pin (arduino/motor shield) is connected to B
to toggle your dc or solenoid do this:
in class project #1a/b:
add a function that controls/triggers the dc motor(a) or solenoid(b) to your project for today.
to do this, you'll have to swap out the dc motor/solenoid for one of your servos!
***pay close attention to your wiring as the dc and solenoid need different voltages!!
***make one side of your breadboard for 12v and the other for 5v.
be sure to include additional key commands to control your new functions!
try this (hint: the solenoid control is already done - just look at the bold commands below):
#include <Stepper.h>
#include <Servo.h>
Servo myservo;
int pos = 0;
// Define how many steps there are in 1 revolution of your motor
#define STEPS_PER_REVOLUTION 200
/**********************************************************/
/* YOU SHOULDN'T HAVE TO CHANGE ANYTHING BETWEEN THIS POINT */
/**********************************************************/
// Set initial default values
unsigned RPM = 45;
unsigned PWM = 150;
unsigned DIR = 1;
void setup()
{
//configure 180 servo on pin digital pin 19
myservo.attach(19); pinMode(18, OUTPUT);//this is where you connect the Base of your transistor
// Change from divide-by-64 prescale on Timer 2 to divide by 8 to get
// 8-times faster PWM frequency (976 Hz --> 7.8 kHz). This should prevent
// overcurrent conditions for steppers with high voltages and low inductance.
TCCR2B = _BV(CS21);
// Now enable PWM and start motion
analogWrite(EN1_PIN, PWM);
analogWrite(EN2_PIN, PWM);
stepper.setSpeed(RPM);
}
/**********************************************************/
/* AND THIS POINT */
/**********************************************************/
void loop()
{
control();
}
void control(){
if (Serial.available()) {
switch (Serial.read()) {
case 'f': case 'F': DIR = 1;
Serial.println("FORWARD");
break;
case 'b': case 'B': DIR =-1;
Serial.println("BACKWARD");
break;
case 'o': case 'O':
if (PWM <= 250) PWM += 5;
Serial.print("PWM="); Serial.println(PWM);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
break;
case 'm': case 'M':
if (PWM >= 150) PWM -= 5;
Serial.print("PWM="); Serial.println(PWM);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
break;
case 'a': case 'A':
RPM++;
Serial.print("RPM="); Serial.println(RPM);
stepper.setSpeed(RPM);
break;
case 'd': case 'D':
if (RPM > 45) RPM--;
Serial.print("RPM="); Serial.println(RPM);
stepper.setSpeed(RPM);
break;
case 'h': case 'H':
printHelp();
break;
case 'i': case 'I':
Serial.println("sweep w/ stepper");
sweep();
break;
case 'j': case 'J':
Serial.println("sweep w/o stepper");
sweep_no_step();
break; case 's': case 'S':
Serial.println("solenoid");
solenoid();
break; default:
Serial.println("Unknown command");
printHelp();
break;
}
}
// This is a busy-wait loop until the inter-step time passes
stepper.step(DIR);
}
void sweep()
{
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
stepper.setSpeed(RPM);
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
stepper.step(DIR);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
stepper.step(DIR);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
void sweep_no_step()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
void solenoid(){
digitalWrite(18, HIGH); // trigger the transistor that triggers the solenoid
delay(100); // wait for 1/10th of a second
digitalWrite(18, LOW); // release the transistor
delay(100); // wait for a 1/10th of a second
}
void printHelp()
{
Serial.println(
"f - forward motion\n"
"b - backwards motion\n"
"a - faster\n"
"d - slower\n"
"o - more power\n"
"m - less power\n"
"i - 180 servo sweep w/ stepper\n"
"j - 180 servo sweep w/o stepper\n" "s - solenoid\n"
);
}
void stop_it(){
delay(10000);
}
assignment
work on your final project
bring materials to work on your final project to next class.
Extension/Enhancement: Every technology extends or amplifies some organ or faculty of the user. What does the medium enhance or intensify?
Closure/Obsolescence: Because there is equilibrium in sensibility, when one area of experience is heightened or intensified, another is diminished or numbed. What is pushed aside or obsolesced by the new medium?
Reversal: Every form, pushed to the limit of its potential, reverses its characteristics.
Retrieval: The content of any medium is an older medium.
drag the some_plugin.rb file to your sketchup plugins folder
***where is the plugin folder???
(1) System Library Folder >Application Support > Google SU 8 > PlugIns
OR
(2) User Folder > Library > Application Support > Google SU 8 > PlugIns
using relays
the sketch from last week will work with a relay, here it is-->
#include <Stepper.h>
#include <Servo.h>
Servo myservo;
int pos = 0;
// Define how many steps there are in 1 revolution of your motor
#define STEPS_PER_REVOLUTION 200
/**********************************************************/
/* YOU SHOULDN'T HAVE TO CHANGE ANYTHING BETWEEN THIS POINT */
/**********************************************************/
// Set initial default values
unsigned RPM = 45;
unsigned PWM = 150;
unsigned DIR = 1;
void setup()
{
//configure 180 servo on pin digital pin 19
myservo.attach(19); pinMode(18, OUTPUT);//this is where you connect the Base of your transistor
// Change from divide-by-64 prescale on Timer 2 to divide by 8 to get
// 8-times faster PWM frequency (976 Hz --> 7.8 kHz). This should prevent
// overcurrent conditions for steppers with high voltages and low inductance.
TCCR2B = _BV(CS21);
// Now enable PWM and start motion
analogWrite(EN1_PIN, PWM);
analogWrite(EN2_PIN, PWM);
stepper.setSpeed(RPM);
}
/**********************************************************/
/* AND THIS POINT */
/**********************************************************/
void loop()
{
control();
}
void control(){
if (Serial.available()) {
switch (Serial.read()) {
case 'f': case 'F': DIR = 1;
Serial.println("FORWARD");
break;
case 'b': case 'B': DIR =-1;
Serial.println("BACKWARD");
break;
case 'o': case 'O':
if (PWM <= 250) PWM += 5;
Serial.print("PWM="); Serial.println(PWM);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
break;
case 'm': case 'M':
if (PWM >= 150) PWM -= 5;
Serial.print("PWM="); Serial.println(PWM);
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
break;
case 'a': case 'A':
RPM++;
Serial.print("RPM="); Serial.println(RPM);
stepper.setSpeed(RPM);
break;
case 'd': case 'D':
if (RPM > 45) RPM--;
Serial.print("RPM="); Serial.println(RPM);
stepper.setSpeed(RPM);
break;
case 'h': case 'H':
printHelp();
break;
case 'i': case 'I':
Serial.println("sweep w/ stepper");
sweep();
break;
case 'j': case 'J':
Serial.println("sweep w/o stepper");
sweep_no_step();
break; case 'r': case 'R':
Serial.println("solenoid");
relay();
break; default:
Serial.println("Unknown command");
printHelp();
break;
}
}
// This is a busy-wait loop until the inter-step time passes
stepper.step(DIR);
}
void sweep()
{
analogWrite(EN1_PIN, PWM); analogWrite(EN2_PIN, PWM);
stepper.setSpeed(RPM);
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
stepper.step(DIR);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
stepper.step(DIR);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
void sweep_no_step()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
void relay(){
digitalWrite(18, HIGH); // trigger the relay that triggers the the solenoid or reversible dc motor
delay(1000); // wait for 1 second
digitalWrite(18, LOW); // release the relay
delay(1000); // wait for 1 second
}
void printHelp()
{
Serial.println(
"f - forward motion\n"
"b - backwards motion\n"
"a - faster\n"
"d - slower\n"
"o - more power\n"
"m - less power\n"
"i - 180 servo sweep w/ stepper\n"
"j - 180 servo sweep w/o stepper\n" "s - relay\n"
);
}
void stop_it(){
delay(10000);
}
converting your manually controlled (via key commands) sketches into internally triggered sketches, a review -->
take a picture, or make a diagram of your electrical connections so that if a wire comes loose you'll be able to put it back quickly.
move your project very carefully
check all connections prior to powering up after moving your project
as you work toward completion be aware of any unexpected sequences/compositions/moments that may be compelling enough to function as a completed project - this is known as a plan b. sometimes, in this medium, your plan be is your best option.
***in other words, you're making a work of art, allow all of your art making skills to be present as you work on this project, and if you discover something cool along the way toward realizing your idea give yourself time to follow it! be an artist at all times, not a factory worker.
be realistic with yourself about time management.
if you have a ton of work to do when you go to sleep on sunday night seriously consider scaling back to your plan b.
assigment
good luck with your final project!
week 15
final crit begins at 5pm
9pm, please turn in all the equipment you've borrowed over the semester.