DOING – ARDUINO

Demonstrating Project in Culture LabPressure Sensor Controlled SolenoidComputer Power SupplyPressure Sensor12v dc SolenoidTIP120 Transistor and diode

Concept: create a robotic musical instrument using a sensor and actuator
Sensor: Pressure sensitive pad
Actuator: Solenoid

Solenoid powered by 12v dc required TIP120 transistor to switch on and link to Arduino (which runs at 5v dc) – the circuit includes a diode to prevent damage to the Arduino caused by “inductive motor kick back”.

Here is the code used:

 

Solenoid Code

/* Solenoid Triggered by Pressure Sensor – 5th May 2010
by Benjamin Freeth, MRes. Digital Media, Culture Lab, Newcastle University

Pressure Sensor connected to Analog 0
Solenoid connected to Digital Pin 3

inputs
*/
int potPinA = 0; // select the input pin for the potentiometer
int solenoidPinA = 3; // select the pin for the solenoid
int valA = 0; // variable to store the value coming from the

void setup() {
pinMode(solenoidPinA, OUTPUT); // declare the ledPin as an OUTPUT}
Serial.begin(9600); // initialize serial communications at 9600 bps:
}
void loop() {
valA = analogRead(potPinA); // read the value from the sensor

Serial.print(“sensor = ” ); // print the results to the serial monitor:
Serial.println(valA); // print the sensor value and a line break to seperate sensor values

if (valA >= 1) // If statement to test variable if greater than or equal to 1 i.e. pressure sensor has not been pressed
{// various resistors could be used to change the sensitivity or range of this sensor? – try this!
digitalWrite(solenoidPinA, LOW); // send the solenoidPinA LOW i.e. switch off the solenoid
}
else if (valA <= 0) // if the sensor value is less than or equal to 0 i.e. the sensor has been pressed
{
digitalWrite(solenoidPinA, HIGH); // solenoidPinA on, switch solenoid on
delay (100);
digitalWrite(solenoidPinA, LOW); // switches solenoid off to stop it burning out
}
}

Wood Pecker Project

From experimenting with this circuit it would be nice to create a project using the trees outside the civic centre, solenoids mounted in the trees could be triggered by PIR or pressure senstive pads. Zigbee radio shields from Libelium could be used to radio to the solenoids in the trees which would create a woodpecker effect and drawing attention from passersby.
Site For SensorSite For Solenoid

Pileated WoodpeckerProgramming The Zigbee's
I used Tom Igoe’s processing sketch to program the zigbee radios:

/*
XBee terminal
Language: processing

This program is a basic serial terminal program.
It replaces newline characters from the keyboard
with return characters. It’s designed for use with
Linux, Unix, and OS X and XBee radios, because the
XBees don’t send newline characters back.
*/
import processing.serial.*;

Serial myPort; // the serial port you’re using
String portnum; // name of the serial port
String outString = “”; // the string being sent out the serial port
String inString = “”; // the string coming in from the serial port
int receivedLines = 0; // how many lines have been received
int bufferedLines = 10; // number of incoming lines to keep

void setup() {
size(400, 300); // window size

// create a font with the second font available to the system:
PFont myFont = createFont(PFont.list()[40], 14);
textFont(myFont);

// list all the serial ports:
println(Serial.list());

// based on the list of serial ports printed from the
//previous command, change the 0 to your port’s number:
portnum = Serial.list()[0];
// initialize the serial port:
myPort = new Serial(this, portnum, 9600);

}

void draw() {
// clear the screen:
background(0);
// print the name of the serial port:
text(“Serial port: ” + portnum, 10, 20);
// Print out what you get:
text(“typed: ” + outString, 10, 40);
text(“received:\n” + inString, 10, 80);
}

// This method responds to key presses when the
// program window is active:
void keyPressed() {
switch (key) {
// in OSX, if the user types return,
// a linefeed is returned. But to
// communicate with the XBee, you want a carriage return:

case ‘\n’:
myPort.write(outString + “\r”);
outString = “”;
break;
case 8: // backspace
// delete the last character in the string:
outString = outString.substring(0, outString.length() -1);
break;
case ‘+’: // we have to send the + signs even without a return:
myPort.write(key);
// add the key to the end of the string:
outString += key;
break;
case 65535: // If the user types the shift key, don’t type anything:
break;
// any other key typed, add it to outString:
default:
// add the key to the end of the string:
outString += key;
break;
}
}

// this method runs when bytes show up in the serial port:
void serialEvent(Serial myPort) {
// read the next byte from the serial port:
int inByte = myPort.read();
// add it to inString:
inString += char(inByte);
if (inByte == ‘\r’) {
// if the byte is a carriage return, print
// a newline and carriage return:
inString += ‘\n’;
// count the number of newlines:
receivedLines++;
// if there are more than 10 lines, delete the first one:
if (receivedLines > bufferedLines) {
deleteFirstLine();
}
}
}
// deletes the top line of inString so that it all fits on the screen:
void deleteFirstLine() {
// find the first newline:
int firstChar = inString.indexOf(‘\n’);
// delete it:
inString= inString.substring(firstChar+1);
}

Xbee Radio Addresses
I used the following addresses for each Xbee radio:

Xbee 1: ATMY 1234 ATDL5678 ATID1111 ATDH0
Xbee 2: ATMY5678 ATDL1234 ATID1111 ATDH0

To test the link up i used the code by Tom Igoe from his Making Things Talk book – turning a potentiometer on one Arduino makes an led brighten or dim on the other arduino and vice versa – the information being transmitted by the Xbee Shields. Here is the code used to test the link up:

Xbee Duplex Code:
/*
XBee Analog Duplex sender
Language: Wiring/Arduino

This sketch configures an XBee radio via the serial port,
sends the value of an analog sensor out, and listens for input
from the radio, using it to set the value of a PWM output.
Thanks to Robert Faludi for the critique and improvements.
*/
#define sensorPin 0 // input sensor
//#define txLed 2 // LED to indicate outgoing data
//#define rxLed 3 // LED to indicate incoming data
#define analogLed 9 // LED that changes brightness with incoming value
#define threshold 10 // how much change you need to see on
// the sensor before sending

int lastSensorReading = 0; // previous state of the switch

int inByte= -1; // incoming byte from serial RX
char inString[6]; // string for incoming serial data
int stringPos = 0; // string index counter

void setup() {
// configure serial communications:
Serial.begin(9600);

// configure output pins:
//pinMode(txLed, OUTPUT);
//pinMode(rxLed, OUTPUT);
pinMode (analogLed, OUTPUT);

// set XBee’s destination address:
setDestination();
// blink the TX LED indicating that the main program’s about to start:
//blink(3);
}
void setDestination() {
// put the radio in command mode:
Serial.print(“+++”);
// wait for the radio to respond with “OK\r”
char thisByte = 0; // what id the value of OK? is this really reading it?
while (thisByte != ‘\r’) {
if (Serial.available() > 0) {
thisByte = Serial.read();
}
}

// set the destination address, using 16-bit addressing.
// if you’re using two radios, one radio’s destination
// should be the other radio’s MY address, and vice versa:

// ok but what about the ATDL? – should this be the other radios or the same – it would make sense to be the other radios but may be for the one this arduino is attazched to – like
//linking the two up ATDL to ATMY ???? need to check this?
Serial.print(“ATDH0\r”);

Serial.print(“ATDL5678\r”); // should this be 1234 too or is this part of the destination address?

//lets try it!
//Serial.print(“ATDL1234\r”); lets stick with the original code for now…

// set my address using 16-bit addressing:
Serial.print(“ATMY1234\r”);
// set the PAN ID. If you’re working in a place where many people
// are using XBees, you should set your own PAN ID distinct
// from other projects.
Serial.print(“ATID1111\r”);
// put the radio in data mode:
Serial.print(“ATCN\r”);
}
/* Blink the tx LED:
void blink(int howManyTimes) {
for (int i=0; i< howManyTimes; i++) {
digitalWrite(txLed, HIGH);
delay(200);
digitalWrite(txLed, LOW);
delay(200);
}
}*/

void loop() {
// listen for incoming serial data:
if (Serial.available() > 0) {
// turn on the RX LED whenever you’re reading data:
//digitalWrite(rxLed, HIGH);
handleSerial();
}
// else {
// turn off the receive LED when there’s no incoming data:
// digitalWrite(rxLed, LOW);
// }

// listen to the potentiometer:
char sensorValue = readSensor();

// if there’s something to send, send it:
if (sensorValue > 0) {
//light the tx LED to say you’re sending:
// digitalWrite(txLed, HIGH);

Serial.print(sensorValue, DEC );
Serial.print(“\r”);

// turn off the tx LED:
// digitalWrite(txLed, LOW);
}
}
void handleSerial() {
inByte = Serial.read();
// save only ASCII numeric characters (ASCII 0 – 9):
if ((inByte >= ‘0’) && (inByte <= ‘9’)){
inString[stringPos] = inByte;
stringPos++;
}
// if you get an ASCII carriage return:

if (inByte == ‘\r’) {
// convert the string to a number:
int brightness = atoi(inString);
// set the analog output LED:
analogWrite(analogLed, brightness);

// put zeroes in the array
for (int c = 0; c < stringPos; c++) {
inString = 0;
}
// reset the string pointer:
stringPos = 0;
}
}

char readSensor() {
char message = 0;
// read the sensor:
int sensorReading = analogRead(sensorPin);

// look for a change from the last reading
// that’s greater than the threshold:
if (abs(sensorReading – lastSensorReading) > threshold) {
message = sensorReading/4;
lastSensorReading = sensorReading;
}
return message;
}

 

MEMORY
Having the ability to remember and replay the triggering of the solenoids will add depth to the project.

To investigate this i have looked at the 8 step tone sequencer on the following site:

http://www.beavisaudio.com/projects/digital/ArduinoPunkConsole/

The code contains arrays which store variables and act as memory.

// Set up the array for each step
int steps[] = {100,120,140,160,180,200,220,240};

A “for loop” is then used to move through the sequence:

void loop() 
{
  // Main sequence loop  
  for (int i=0; i<8; i++)

The version i built:

8 Step SequencerSerialy Enabled LCDMomentary SwitchPotentiometers

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I changed some of the original source code to create an animation on the LCD screen and also had to switch off the spash screen the LCD came programmed with:

 

/* ======================================================================
 Arduino Punk Console
 A simple programmable 8 step tone sequencer 
 by dano/beavisaudio.com
 Revs
 ———————————–
 15 Sept  djh  initial version
 
——————————————-
digital in changed from highs to lows in code to make this work after using 8 input to serial sketch!
formating and text to serial print on lcd changed
to do:
make controls for screen brightness / contrast etc – which byte command controls contrast?
read value from the volume control to create a read out on the screen
use the screen to represent music (music isn’t played!)
max patch that analyses note values and then searches the internet for words this number of words into a
piece of text – this will enable poetry and stochastic interactions between unrelated words!!!!!
something made of fragments
last letter of each word could be turned back into music!
add explanations for the letters v etc at start up!
======================================================================*/
// Map all the input and output pins
#define AnalogInFrequency 1
#define AnalogInTempo 2
#define AnalogInDuration 0
//#define AnalogInVolume 3 // this will measure the volume level? on analog pin3 – volume pot is set up as voltage divider!
#define DigitalOutSignal 11 //how to measure the volume and print this out on the displayanother analog in from this value?
#define DigitalInSwitch0 2
#define DigitalInSwitch1 3
#define DigitalInSwitch2 4
#define DigitalInSwitch3 5
#define DigitalInSwitch4 6
#define DigitalInSwitch5 7
#define DigitalInSwitch6 8
#define DigitalInSwitch7 9 
#define DigitalInStartStop 10
#define DigitalOutLED 12
// Set up the array for each step
int steps[] = {100,120,140,160,180,200,220,240};
// misc housekeeping
int duration = 50;
int pitchval = 1;
int volume = 0; // this is where info from analog
int fPlayMode = true;
int lastPushedStep = -1;
// Initialize the tempo
int tempo = 100;
void setup()
  // setup pin modes (Digital pins are input by default, but
  // I like to set ’em explicitly just so the code is clear.
  pinMode (DigitalInSwitch0, INPUT);
  pinMode (DigitalInSwitch1, INPUT);
  pinMode (DigitalInSwitch2, INPUT);
  pinMode (DigitalInSwitch3, INPUT);
  pinMode (DigitalInSwitch4, INPUT);
  pinMode (DigitalInSwitch5, INPUT);
  pinMode (DigitalInSwitch6, INPUT);
  pinMode (DigitalInSwitch7, INPUT);                
  pinMode (DigitalInStartStop, INPUT);
  pinMode (DigitalOutSignal, OUTPUT);  
  pinMode (DigitalOutLED, OUTPUT);
  // setup comms for the LCD display
  Serial.begin(9600);
  
//Serial.print (0x7C);//(124, DEC); ///these commands switch off the splash screen message (sending this again will enable the splash screen
  //Serial.print (0x09);//(9, DEC);// so if upload code twice then it will switch off and back on again) this needs to be in a seperate sketch
  //these are now in SPLASHSCREEN_ON_OFF.pde)
  
  StartupMessage();// how to reprogram start up message? how to make screen flash with tempo?
void StartupMessage()
{
  
  
  clearLCD();
  delay(2000);
  Serial.print (”     _”);
  delay(100);
  clearLCD();
  
  Serial.print (”     *”);
  delay(100);
  clearLCD();
  
  Serial.print (”     @”);
  delay(100);
  clearLCD();
 
  Serial.print (”     &”);
  delay(100);
  clearLCD();
  
  Serial.print (”     <“);
  delay(100);
  clearLCD();
  
  Serial.print (”     £”);
  delay(100);
  clearLCD();
  
  Serial.print (”     *”);
  delay(100);
  clearLCD();
  
  Serial.print (”     8″);
  delay(500);
  clearLCD();
  
  Serial.print (”     8 +”);
  delay(100);
  clearLCD();
  delay(50);
  Serial.print (”     8 -“);
  delay(100);
  clearLCD();
  delay(50);
  Serial.print (”     8 £”);
  delay(100);
  clearLCD();
  delay(50);
  Serial.print (”     8 %”);
  delay(100);
  clearLCD();
 
  delay(100);
  Serial.print (”     8 @”);
  delay(100);
  
  clearLCD();
  delay(100);
  Serial.print (”     8 ?”);
  delay(100);
  
    clearLCD();
  Serial.print (”     8 S+”);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 S-“);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 S£”);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 S%”);
  delay(100);
  clearLCD();
 
  delay(100);
  Serial.print (”     8 S@”);
  delay(100);
  
  clearLCD();
  delay(100);
  Serial.print (”     8 S?”);
  delay(100);
    clearLCD();
  
  Serial.print (”     8 ST+”);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 ST-“);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 ST£”);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 ST%”);
  delay(100);
  clearLCD();
 
  delay(100);
  Serial.print (”     8 ST@”);
  delay(100);
  
  clearLCD();
  delay(100);
  Serial.print (”     8 ST?”);
  delay(100);
  
  clearLCD();
  
  
  Serial.print (”     8 STE+”);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 STE-“);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 STE£”);
  delay(100);
  clearLCD();
  delay(100);
  Serial.print (”     8 STE%”);
  delay(100);
  clearLCD();
 
  delay(100);
  Serial.print (”     8 STE@”);
  delay(100);
  
  clearLCD();
  delay(100);
  Serial.print (”     8 STE?”);
  delay(100);
  
  clearLCD();
  
  
  Serial.print (”     8 STEP”);//what is the byte command for the cursor to make this animate and type this out?
  delay(1000);
  Serial.print (254, BYTE);
  Serial.print (192, BYTE);
  Serial.print (”   SEQUENCER!”);
  delay (3000);
  
  
  
  
  clearLCD();
  delay(1000);//these delays after clearLCD create a fade out?
  Serial.print (”  INSTRUCTIONS”);
  delay(50);
  clearLCD();
  Serial.print (254, BYTE);
  Serial.print (192, BYTE);
  Serial.print (”  INSTRUCTIONS”);
  delay(2000);
  clearLCD();
  delay(1000);
  Serial.print (” T = Tempo”);//what is the byte command for the cursor to make this animate and type this out?
  delay(2000);
  clearLCD();
  delay(1000);
  Serial.print (254, BYTE);
  Serial.print (192, BYTE);
  Serial.print (” D = Duration”);//how to make text animate from the side?
  delay (2000);
  clearLCD();
  delay(1000);
  Serial.print (” S = Step”);//what is the byte command for the cursor to make this animate and type this out?
  delay(2000);
  clearLCD();
   delay(1000);
   Serial.print (254, BYTE);
  Serial.print (192, BYTE);
  Serial.print (” ARE YOU READY?”);//how to make text animate from the side?
  delay (100);
  clearLCD();
   Serial.print (” ARE YOU READY?”);//how to make text animate from the side?
  delay (100);
  clearLCD();
  Serial.print (254, BYTE);
  Serial.print (192, BYTE);
   Serial.print (” ARE YOU READY?”);//how to make text animate from the side?
  delay (100);
  clearLCD();
   Serial.print (” ARE YOU READY?”);//how to make text animate from the side?
  delay (100);
  clearLCD();
  Serial.print (254, BYTE);
  Serial.print (192, BYTE);
   Serial.print (” ARE YOU READY?”);//how to make text animate from the side?
  delay (100);
  clearLCD();
   Serial.print (” ARE YOU READY?”);//how to make text animate from the side?
  delay (2000);
  clearLCD();
  delay (2000);
  //Serial.print (“PRESS MY BUTTONS”);
}
void clearLCD()
{
  Serial.print(254, BYTE);
  Serial.print(1, BYTE);
}
void loop() 
{
  // Main sequence loop  
  for (int i=0; i<8; i++)
  {   
    // Are we playing or stopping?
    fPlayMode = digitalRead (DigitalInStartStop);
    digitalWrite (DigitalOutLED, HIGH);
    // Check the Hardware
     readSwitches();
     readPots();
    // update the display
    updateDisplay();
    // Make the noise
    if (fPlayMode)
    {
      freqout (steps[i], duration);
    }
    digitalWrite (DigitalOutLED, LOW);
    // Pause between steps
    delay (tempo);       
  }
void updateDisplay() // how to make a brightness contrast controls for the screen?
{
 clearLCD();///added
  Serial.print (“PRESS MY BUTTONS”);//added to try to get rid of bug in values
 //Serial.print (“V:”);
  //Serial.print (volume);
  Serial.print (254, BYTE);
  Serial.print (192, BYTE);
  Serial.print (“T:”);
  Serial.print (tempo / 10);
  Serial.print (” D:”);
  Serial.print (duration / 10);
 if (lastPushedStep != -1)
 {
   Serial.print (”  “);
    Serial.print (“S:”);
    Serial.print (lastPushedStep);
 }
}
// Read the current values of the pots, called from the loop.
void readPots ()
{
    tempo = (analogRead (AnalogInTempo) * 1.9);
    duration = (analogRead (AnalogInDuration));  
    //volume = (analogRead (AnalogInVolume) /6);    
}
// Read the current values of the switches and
// if pressed, replace the switch’s slot frequency
// by reading the frequency pot.
void readSwitches()
{
  // reset last pushed button number
  lastPushedStep = -1;
  // check switch 0, if pressed, get the current freq into step 0, etc. etc.
  if (digitalRead (DigitalInSwitch0) == LOW)
  {
    steps[0] = analogRead(AnalogInFrequency);
    lastPushedStep = 1;
  }
  else if (digitalRead (DigitalInSwitch1) == LOW)
  {
    steps[1] = analogRead(AnalogInFrequency);
    lastPushedStep = 2;
  }
  else if (digitalRead (DigitalInSwitch2) == LOW)
  {
    steps[2] = analogRead(AnalogInFrequency);
    lastPushedStep = 3;
  }
  else if (digitalRead (DigitalInSwitch3) == LOW)
  {
    steps[3] = analogRead(AnalogInFrequency);
    lastPushedStep = 4;
  }
  else if (digitalRead (DigitalInSwitch4) == LOW)
  {
    steps[4] = analogRead(AnalogInFrequency);
    lastPushedStep = 5;
  }
  else if (digitalRead (DigitalInSwitch5) == LOW)
  {
    steps[5] = analogRead(AnalogInFrequency);
    lastPushedStep = 6;
  }
  else if (digitalRead (DigitalInSwitch6) == LOW)
  {
    steps[6] = analogRead(AnalogInFrequency);
    lastPushedStep = 7;
  }
  else if (digitalRead (DigitalInSwitch7) == LOW)
  { 
    steps[7] = analogRead(AnalogInFrequency);
    lastPushedStep = 8;
  }
}
//freqout code by Paul Badger 
// freq – frequency value
// t – time duration of tone
void freqout(int freq, int t) 
  int hperiod;     //calculate 1/2 period in us 
  long cycles, i; 
  // subtract 7 us to make up for digitalWrite overhead – determined empirically 
  hperiod = (500000 / ((freq – 7) * pitchval));             
  // calculate cycles 
  cycles = ((long)freq * (long)t) / 1000;    // calculate cycles 
  for (i=0; i<= cycles; i++)
  {              // play note for t ms  
    digitalWrite(DigitalOutSignal, HIGH);  
    delayMicroseconds(hperiod); 
    digitalWrite(DigitalOutSignal, LOW);  
    delayMicroseconds(hperiod – 1);     // – 1 to make up for fractional microsecond in digitaWrite overhead 
  } 
}
 

Demonstrating the 8 Step Sequencer:

Demonstrating Project


Comments (0)

INTERACTIVE GONG MUSIC

GONGCONCEPT

Comments (0)