Well, that's that for another year (academically speaking), but this blog will continue..
Last two projects were a bit of a frost - got most of the Minor Project posted, but i suspect hardware & programming logic problems, as i couldn't get it to do what i thought it should - it kept doing what i actually had told it to do.
As a poster i once saw says:
* I Know You Believe You Understood
* What It Was That You Though I Said,
* But I'm Not Sure You Realise
* That What You Thought You Heard
* Was NOT What I Meant!!
i can hear my Arduino chortling away at that thought, since it seems to me that what i thought i'd told it to do was something other than what i wanted {sigh}..
Always assuming the hardware works as expected, of course..
This is about robots & automation. It's a companion blog to JaneMareesTech, which is about the Arduino microcontroller system & related electronics
Showing posts with label interrupts. Show all posts
Showing posts with label interrupts. Show all posts
Friday, November 25, 2011
All over bar the groaning..
Labels:
hardware,
humour,
interrupts,
PROJECTS,
TASKS
Monday, November 21, 2011
Projects -- Interrupts: Mark II
/*
* Project: Project_interrupt
* Author: Jane-Maree Howard
* Date: Monday 21/11/2011
* Platform: Arduino 22
* Purpose: To demonstrate an interrupt on Digital pin 3
* Operation: Description: Connect a 20kilOhm resistor from
* digital pin3 to digital pin13!
* Earlier problem solved as we now have a hardware feedback
* from OUTPUT digi-pin13 to INPUT digi-pin3,
* to which the interrupt is attached.
* The digital flip-flop occurs every second, is fed to digi-pin3,
* which registers the change & triggers the interrupt,
* which, in turn, calls blink() where the pin state variable is flipped.
* This state change is fed back via digi-pin13 to digi-pin3, triggering
* the interrupt once again.
*/
int iPin13 = 13;
int iPin3 = 3;
volatile int iState = LOW;
void setup()
{
// open Serial port
Serial.begin(9600);
// set pin13, pin3 as OUTPUTs
pinMode(iPin13, OUTPUT);
pinMode(iPin3, INPUT);
// interrupt1 calls blink() when pin13 flip-flops
attachInterrupt(1, blink, CHANGE);
digitalWrite(iPin3, iState);
Serial.println("\nStart\n");
}//setup()
void loop()
{
// delay 1 second
delay(1000);
// in effect, flip pin13
Serial.println(iState);
digitalWrite(iPin13, iState);
digitalWrite(iPin3, iState);
}//loop()
void blink()
{
// flip value to trigger interrupt
iState = !iState;
}//blink()
//END
i finally cracked it!
most annoying though..
..but when i wondered about which pin the interrupt operated on, i went back to the appropriate page..
..where i saw that interrupt-0 can be attached to digital pin 2, & interrupt-1 to digital pin 3.
after that, it was pretty much plain sailing - the feedback resistor instead of some weird software, & as can be seen at left, it works beeootifly-thank-yew!
on to my next problem: how can i use LDR hardware to trigger an interrupt (for my "fridge door open" stuff!
{sigh of relief!}.
* Project: Project_interrupt
* Author: Jane-Maree Howard
* Date: Monday 21/11/2011
* Platform: Arduino 22
* Purpose: To demonstrate an interrupt on Digital pin 3
* Operation: Description: Connect a 20kilOhm resistor from
* digital pin3 to digital pin13!
* Earlier problem solved as we now have a hardware feedback
* from OUTPUT digi-pin13 to INPUT digi-pin3,
* to which the interrupt is attached.
* The digital flip-flop occurs every second, is fed to digi-pin3,
* which registers the change & triggers the interrupt,
* which, in turn, calls blink() where the pin state variable is flipped.
* This state change is fed back via digi-pin13 to digi-pin3, triggering
* the interrupt once again.
*/
int iPin13 = 13;
int iPin3 = 3;
volatile int iState = LOW;
void setup()
{
// open Serial port
Serial.begin(9600);
// set pin13, pin3 as OUTPUTs
pinMode(iPin13, OUTPUT);
pinMode(iPin3, INPUT);
// interrupt1 calls blink() when pin13 flip-flops
attachInterrupt(1, blink, CHANGE);
digitalWrite(iPin3, iState);
Serial.println("\nStart\n");
}//setup()
void loop()
{
// delay 1 second
delay(1000);
// in effect, flip pin13
Serial.println(iState);
digitalWrite(iPin13, iState);
digitalWrite(iPin3, iState);
}//loop()
void blink()
{
// flip value to trigger interrupt
iState = !iState;
}//blink()
//END
i finally cracked it!
most annoying though..
..but when i wondered about which pin the interrupt operated on, i went back to the appropriate page..
..where i saw that interrupt-0 can be attached to digital pin 2, & interrupt-1 to digital pin 3.
after that, it was pretty much plain sailing - the feedback resistor instead of some weird software, & as can be seen at left, it works beeootifly-thank-yew!
on to my next problem: how can i use LDR hardware to trigger an interrupt (for my "fridge door open" stuff!
{sigh of relief!}.
Labels:
Arduino,
hardware,
interrupts,
PROJECTS,
serial monitor,
software
Projects -- Interrupts
/* example of interrupt function using Arduino 22 */
int iPin = 13;
volatile int iState = LOW;
void setup()
{
// open Serial
Serial.begin(9600);
// set pin13 as OUTPUT
pinMode(iPin, OUTPUT);
// interrupt1 calls blink() when pin13 flip-flops
attachInterrupt(1, blink, CHANGE);
digitalWrite(iPin, 1);
Serial.println("\nStart\n");
}//setup()
void loop()
{
// delay 1 second
delay(1000);
// in effect, flip pin13
Serial.println(iState);
digitalWrite(iPin, iState);
}//loop()
void blink()
{
// flip value to trigger interrupt
iState = !iState;
}//blink()
//END
i have been trying to get this interrupt program to work - it doesn't alternate the way i think/assume it should.
it just changes at random, sometimes acting like a touch or proximity switch!
i'm baffled :-?
here's where the example code came from - i've modified it to produce a serial monitor output, & inserted another digitalWrite() statement in the setup to try to get the thing triggering regularly..
..but it doesn't {sigh}..
int iPin = 13;
volatile int iState = LOW;
void setup()
{
// open Serial
Serial.begin(9600);
// set pin13 as OUTPUT
pinMode(iPin, OUTPUT);
// interrupt1 calls blink() when pin13 flip-flops
attachInterrupt(1, blink, CHANGE);
digitalWrite(iPin, 1);
Serial.println("\nStart\n");
}//setup()
void loop()
{
// delay 1 second
delay(1000);
// in effect, flip pin13
Serial.println(iState);
digitalWrite(iPin, iState);
}//loop()
void blink()
{
// flip value to trigger interrupt
iState = !iState;
}//blink()
//END
i have been trying to get this interrupt program to work - it doesn't alternate the way i think/assume it should.
it just changes at random, sometimes acting like a touch or proximity switch!
i'm baffled :-?
here's where the example code came from - i've modified it to produce a serial monitor output, & inserted another digitalWrite() statement in the setup to try to get the thing triggering regularly..
..but it doesn't {sigh}..
Labels:
Arduino,
interrupts,
PROJECTS,
serial monitor,
software
Sunday, September 25, 2011
Project 3 -- Minor Project: schematic
this is the best i could do - i don't know how to make circuit jumper in Fritzing but it should be obvious that that's what they are, not connections..
The 3 'wriggly' things are Peltier elements (Thermistors)
The 3 'wriggly' things are Peltier elements (Thermistors)
Labels:
EEPROM,
fritzing,
functions,
hardware,
interrupts,
LED,
MINOR PROJECT,
photocell,
PROJECTS,
schematic,
sensors,
serial monitor,
thermistor
Project 3 -- Minor Project: software
/*
* Project: Minor_Project_621
* Author: Jane-Maree Howard
* Date: Wednesday 21/09/2011
* Platform: Arduino 22
* Purpose: To demonstate a fridge-control robot
* Operation: Several thermistors are mounted inside the fridge.
* Their values are read in sequence at 1-minute intervals,
* their average is calculated, & the values & their average stored in EEPROM
* A LDR is also mounted inside the fridge, to detect when the door is opened.
* Change in the LDR resistance trigers an interrupt, & this is also recorded.
Declare:
Setup():
Loop():
*/
#include // EEPROM library
int iAnalogPin[] = {0,1,2,3}; // analog pin numbers
int iLEDpin = 13; // door-open LED
int iDarkLevel = 100; // pre-set photocell reading triggering interrupt
int iGetData = 0; // get signal to retrieve data
int iHeading = 0; // signal to print heading
int iSecond = 1000; // 1 second delay &..
int iMinute = 60000; // ..1 minute delay
int iTemperature[3]; // temperature readings from A0 - A2
int iAvgTemp; // Average of the 3 temperatures
volatile byte iAddressCount = 0; // EEPROM address counter
volatile byte bLEDstate = 0; // LED pin ON or OFF
/* all operations are performed in the setup() section of the program */
void setup()
{
delay(iSecond*5); // up to 10 minute delay
pinMode(iLEDpin, OUTPUT); // LED-pin is an output..
digitalWrite(iLEDpin,LOW); // ..initially turned off
Serial.begin(9600); // SM @ 9600baud
// attach interrupt 0, to digital pin 2
attachInterrupt(0, DoorOpen, CHANGE); // ..on CHANGE
iGetData = KeypressInput(); // check for receiving data
while (iGetData == 0) // if no signal,start reading..
{
// stop interrupts while reading
noInterrupts(); // stop interrupts while reading
iAvgTemp = 0; // zero average Temperature vble
/* First read the 3 values into iTemperature[] .. */
for (byte j=0; j<3; j++)
{
// read value on 3 thermistor pins i.e. iAnalogPin[j]
iTemperature[j] = analogRead(iAnalogPin[j]);
// now we have to map 0-1023 to 0-255..
// ..since we want to store the values as bytes..
iTemperature[j] = map(iTemperature[j], 0, 1023, 0, 255);
// ..& write them to EEPROM
EEPROM.write(iAddressCount, iTemperature[j]);
// increment the address count..
iAddressCount++ ;
iAvgTemp += iTemperature[j]; // add to average total
// delay 10 milliseconds
delay(10);
}//for(j)
iAvgTemp = (int)(iAvgTemp/3);
// write Average to EEPROM also..
EEPROM.write(iAddressCount, iAvgTemp);
// ..& increment the address count.
iAddressCount++ ;
interrupts(); // re-enable interrupts
// debugging
Serial.print("\nrecorded data\t");
for (int j=0;j<3;j++)
Serial.print(iTemperature[j]);
Serial.print(iAvgTemp);
delay(iMinute); // delay 1 minute..
iGetData = KeypressInput(); // ..then check for receiving data
}// while(==0) */
while (iGetData != 0) // ..otherwise, retrieve stored data & send to SM
{
if (iHeading%20 == 0)
Heading();
iHeading++;
//diagnostic stuff & logic testing
if (iHeading > 100)
{
iGetData = 0; // check for receiving data
iHeading = 0;
}//if()
}// while(!=0)
}// end setup()
void loop()
{/*nothing done in here*/}//end loop()
/* prints heading to Serial Monitor at pre-set intervals */
void Heading()
{
Serial.println("\nTemperatures\tT0\tT1\tT2\tT3\tAverage\tDoor\n");
}//Heading()
//END
LIBRARY FUNCTIONS:
/*
* Project: LIB04_KeypressInput
* Author: Jane-Maree Howard
* Date: Saturday 08/10/2011
* Platform: Arduino 22
* Purpose: To make a library function for inputting a key-press via Serial comm link
* Operation: Description: inputs a key-press & returns an Integer
- Declare: NONE - MUST BE DECLARED IN CONJOINING SKETCH(ES)
- Setup(): NONE - MUST BE USED ONLY IN CONJOINING SKETCH(ES)
- (used only in testing)
- Procedure(): int KeypressInput(); no parameters
- Loop(): NONE - MUST BE USED ONLY IN CONJOINING SKETCH(ES)
- (used only in testing)
*/
int KeypressInput()
{
/* inputs a keypress via the Serial comms link
& returns a non-zero Integer only if there is an input
CALLED IN MAIN SKETCH */
int iKey = 0;
// send data only when you receive data
if (Serial.available() > 0)
iKey = Serial.read();
return iKey;
}//KeypressInput()
//END
/*
* Project: LIB09_photocell_interrupt
* Author: Jane-Maree Howard
* Date: Thursday 24/11/2011
* Platform: Arduino 22
* Purpose: To make a Photocell Switch for an interrupt pin (digital 2 or 3).
* Operation: The circuit arrangement is the same as the ladyada
* LED dimmer, but here the software has a trigger threshold
* for turning the interrupt pin on.
* The output of the Analog pin is measured as before,
* but instead of analogWrite() to the interrupt pin,
* digitalWrite is used to switch the pin on or off.
* We don't need to map the Analog pin output,
* since it's merely a trigger.
* Original description:
* "Connect one end of the photocell to 5V, the other end to Analog 0.
* Then connect one end of a 4.7K resistor from Analog 0 to ground
* Connect LED from pin 9 through a resistor to ground"
* Declare, Setup(), Loop():
* NONE - MUST BE USED ONLY IN CONJOINING SKETCH(ES)
- Procedure(): void PhotocellTrigger(int,int,int);
- void DoorOpen();
*/
/* the photocell pin value is tracked by the interrupt */
void PhotocellTrigger(int iInterruptPin, int iPhotoPin, int iDark)
{
int iPhotoReading = analogRead(iPhotoPin); //i.e. analog 0
//we now use our 'darkLevel' variable to trigger the LED ON.
if (iPhotoReading > iDark)
digitalWrite(iInterruptPin, HIGH); // turn InterruptPin on, else..
else
digitalWrite(iInterruptPin, LOW); // ..turn InterruptPin off
}//PhotocellTrigger()
/* called when the Interrupt is triggered - records door state */
void DoorOpen()
{
digitalWrite(iLEDpin, bLEDstate); // Turn door-open LED ON or OFF..
EEPROM.write(iAddressCount, bLEDstate);// ..record the incident..
iAddressCount++; // .. increment address count..
bLEDstate = !bLEDstate; // ..& change LED-state ON to OFF or vice versa
}//DoorOpen()
//END
* Project: Minor_Project_621
* Author: Jane-Maree Howard
* Date: Wednesday 21/09/2011
* Platform: Arduino 22
* Purpose: To demonstate a fridge-control robot
* Operation: Several thermistors are mounted inside the fridge.
* Their values are read in sequence at 1-minute intervals,
* their average is calculated, & the values & their average stored in EEPROM
* A LDR is also mounted inside the fridge, to detect when the door is opened.
* Change in the LDR resistance trigers an interrupt, & this is also recorded.
Declare:
Setup():
Loop():
*/
#include
int iAnalogPin[] = {0,1,2,3}; // analog pin numbers
int iLEDpin = 13; // door-open LED
int iDarkLevel = 100; // pre-set photocell reading triggering interrupt
int iGetData = 0; // get signal to retrieve data
int iHeading = 0; // signal to print heading
int iSecond = 1000; // 1 second delay &..
int iMinute = 60000; // ..1 minute delay
int iTemperature[3]; // temperature readings from A0 - A2
int iAvgTemp; // Average of the 3 temperatures
volatile byte iAddressCount = 0; // EEPROM address counter
volatile byte bLEDstate = 0; // LED pin ON or OFF
/* all operations are performed in the setup() section of the program */
void setup()
{
delay(iSecond*5); // up to 10 minute delay
pinMode(iLEDpin, OUTPUT); // LED-pin is an output..
digitalWrite(iLEDpin,LOW); // ..initially turned off
Serial.begin(9600); // SM @ 9600baud
// attach interrupt 0, to digital pin 2
attachInterrupt(0, DoorOpen, CHANGE); // ..on CHANGE
iGetData = KeypressInput(); // check for receiving data
while (iGetData == 0) // if no signal,start reading..
{
// stop interrupts while reading
noInterrupts(); // stop interrupts while reading
iAvgTemp = 0; // zero average Temperature vble
/* First read the 3 values into iTemperature[] .. */
for (byte j=0; j<3; j++)
{
// read value on 3 thermistor pins i.e. iAnalogPin[j]
iTemperature[j] = analogRead(iAnalogPin[j]);
// now we have to map 0-1023 to 0-255..
// ..since we want to store the values as bytes..
iTemperature[j] = map(iTemperature[j], 0, 1023, 0, 255);
// ..& write them to EEPROM
EEPROM.write(iAddressCount, iTemperature[j]);
// increment the address count..
iAddressCount++ ;
iAvgTemp += iTemperature[j]; // add to average total
// delay 10 milliseconds
delay(10);
}//for(j)
iAvgTemp = (int)(iAvgTemp/3);
// write Average to EEPROM also..
EEPROM.write(iAddressCount, iAvgTemp);
// ..& increment the address count.
iAddressCount++ ;
interrupts(); // re-enable interrupts
// debugging
Serial.print("\nrecorded data\t");
for (int j=0;j<3;j++)
Serial.print(iTemperature[j]);
Serial.print(iAvgTemp);
delay(iMinute); // delay 1 minute..
iGetData = KeypressInput(); // ..then check for receiving data
}// while(==0) */
while (iGetData != 0) // ..otherwise, retrieve stored data & send to SM
{
if (iHeading%20 == 0)
Heading();
iHeading++;
//diagnostic stuff & logic testing
if (iHeading > 100)
{
iGetData = 0; // check for receiving data
iHeading = 0;
}//if()
}// while(!=0)
}// end setup()
void loop()
{/*nothing done in here*/}//end loop()
/* prints heading to Serial Monitor at pre-set intervals */
void Heading()
{
Serial.println("\nTemperatures\tT0\tT1\tT2\tT3\tAverage\tDoor\n");
}//Heading()
//END
* Project: LIB04_KeypressInput
* Author: Jane-Maree Howard
* Date: Saturday 08/10/2011
* Platform: Arduino 22
* Purpose: To make a library function for inputting a key-press via Serial comm link
* Operation: Description: inputs a key-press & returns an Integer
- Declare: NONE - MUST BE DECLARED IN CONJOINING SKETCH(ES)
- Setup(): NONE - MUST BE USED ONLY IN CONJOINING SKETCH(ES)
- (used only in testing)
- Procedure(): int KeypressInput(); no parameters
- Loop(): NONE - MUST BE USED ONLY IN CONJOINING SKETCH(ES)
- (used only in testing)
*/
int KeypressInput()
{
/* inputs a keypress via the Serial comms link
& returns a non-zero Integer only if there is an input
CALLED IN MAIN SKETCH */
int iKey = 0;
// send data only when you receive data
if (Serial.available() > 0)
iKey = Serial.read();
return iKey;
}//KeypressInput()
//END
* Project: LIB09_photocell_interrupt
* Author: Jane-Maree Howard
* Date: Thursday 24/11/2011
* Platform: Arduino 22
* Purpose: To make a Photocell Switch for an interrupt pin (digital 2 or 3).
* Operation: The circuit arrangement is the same as the ladyada
* LED dimmer, but here the software has a trigger threshold
* for turning the interrupt pin on.
* The output of the Analog pin is measured as before,
* but instead of analogWrite() to the interrupt pin,
* digitalWrite is used to switch the pin on or off.
* We don't need to map the Analog pin output,
* since it's merely a trigger.
* Original description:
* "Connect one end of the photocell to 5V, the other end to Analog 0.
* Then connect one end of a 4.7K resistor from Analog 0 to ground
* Connect LED from pin 9 through a resistor to ground"
* Declare, Setup(), Loop():
* NONE - MUST BE USED ONLY IN CONJOINING SKETCH(ES)
- Procedure(): void PhotocellTrigger(int,int,int);
- void DoorOpen();
*/
/* the photocell pin value is tracked by the interrupt */
void PhotocellTrigger(int iInterruptPin, int iPhotoPin, int iDark)
{
int iPhotoReading = analogRead(iPhotoPin); //i.e. analog 0
//we now use our 'darkLevel' variable to trigger the LED ON.
if (iPhotoReading > iDark)
digitalWrite(iInterruptPin, HIGH); // turn InterruptPin on, else..
else
digitalWrite(iInterruptPin, LOW); // ..turn InterruptPin off
}//PhotocellTrigger()
/* called when the Interrupt is triggered - records door state */
void DoorOpen()
{
digitalWrite(iLEDpin, bLEDstate); // Turn door-open LED ON or OFF..
EEPROM.write(iAddressCount, bLEDstate);// ..record the incident..
iAddressCount++; // .. increment address count..
bLEDstate = !bLEDstate; // ..& change LED-state ON to OFF or vice versa
}//DoorOpen()
//END
Labels:
Arduino,
EEPROM,
functions,
interrupts,
LED,
libraries,
MINOR PROJECT,
photocell,
PROJECTS,
sensors,
serial monitor,
software,
thermistor
Thursday, September 22, 2011
Task 31B -- Making Use of Interrupts
..
Again the schematic is from the Code Project/Interrupts site.
(I had to use a 150Ohm resistor because i couldn't find my push-switch!
It didn't work quite as well - i should really find that switch! - but i
suspect my wobbly hand had a lot to do with it; i could try 'de-bouncing'
the 'switch', but delay() won't work inside the interrupt-triggered function
(find the switch, stoopid!) )
This time, however, the code makes use of a Hardware Interrupt, as follows:
/*
* Project: Interrupts_part_B_621task31
* Author: DaveAuld, tidied (not much! :-) ) by Jane-Maree Howard
* Date: 23 Feb 2010
* Platform: Arduino 22
* Purpose: To demonstrate a simple interrupt-triggered LED-switch
* Operation: Description:
* "Set up the Arduino as per the schematic
* and upload the code below to the microprocessor.
* We will use the same schematic diagram and
* modify the code to make use of hardware interrupts.
* Now when you upload the code, the LED changes state
* whenever the button is pressed
* even though the code is still running the same long delay
* in the main loop.
* [This is code PART B in the downloaded source file.]"
*/
int pbIn = 0; // Interrupt 0 is on DIGITAL PIN 2!
int ledOut = 4; // The output LED pin
volatile int state = LOW; // The input state toggle
void setup()
{
// Set up the digital pin 2 to an Interrupt and Pin 4 to an Output
pinMode(ledOut, OUTPUT);
//Attach the interrupt to the input pin and monitor for ANY Change
attachInterrupt(pbIn, stateChange, CHANGE);
}//setup()
void loop()
{
//Simulate a long running process or complex task
for (int i = 0; i < 100; i++)
{
// do nothing but waste some time
delay(50); // Jane-Maree increases delay time from 10ms to 50ms
}//for()
}//loop()
void stateChange()
{
state = !state;
digitalWrite(ledOut, state);
}//stateChange()
//END
Again the schematic is from the Code Project/Interrupts site.
(I had to use a 150Ohm resistor because i couldn't find my push-switch!
It didn't work quite as well - i should really find that switch! - but i
suspect my wobbly hand had a lot to do with it; i could try 'de-bouncing'
the 'switch', but delay() won't work inside the interrupt-triggered function
(find the switch, stoopid!) )
This time, however, the code makes use of a Hardware Interrupt, as follows:
/*
* Project: Interrupts_part_B_621task31
* Author: DaveAuld, tidied (not much! :-) ) by Jane-Maree Howard
* Date: 23 Feb 2010
* Platform: Arduino 22
* Purpose: To demonstrate a simple interrupt-triggered LED-switch
* Operation: Description:
* "Set up the Arduino as per the schematic
* and upload the code below to the microprocessor.
* We will use the same schematic diagram and
* modify the code to make use of hardware interrupts.
* Now when you upload the code, the LED changes state
* whenever the button is pressed
* even though the code is still running the same long delay
* in the main loop.
* [This is code PART B in the downloaded source file.]"
*/
int pbIn = 0; // Interrupt 0 is on DIGITAL PIN 2!
int ledOut = 4; // The output LED pin
volatile int state = LOW; // The input state toggle
void setup()
{
// Set up the digital pin 2 to an Interrupt and Pin 4 to an Output
pinMode(ledOut, OUTPUT);
//Attach the interrupt to the input pin and monitor for ANY Change
attachInterrupt(pbIn, stateChange, CHANGE);
}//setup()
void loop()
{
//Simulate a long running process or complex task
for (int i = 0; i < 100; i++)
{
// do nothing but waste some time
delay(50); // Jane-Maree increases delay time from 10ms to 50ms
}//for()
}//loop()
void stateChange()
{
state = !state;
digitalWrite(ledOut, state);
}//stateChange()
//END
Subscribe to:
Posts (Atom)