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..

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..

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!}.

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}..

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)

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

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