/* PROTO I/Os arduino PCB TESTER. This code tests all the devices in the PROTO I/Os arduino V1.0 PCB shield. Four buttons, buttons 3 and 4 have melodys. Buttons 1 and 2 switch between a light sequence on the board LEDs, or outputs the temperature read by (DS18S20, DS18B20, DS1822) has a binary value on to the LEDs. By Jony Silva, www.electropepper.org , 20/4/2014 V1.0 */ #include "pitches.h" #include #define ON 1 #define OFF 0 #define BUTTON_1 8 #define BUTTON_2 9 #define BUTTON_3 10 #define BUTTON_4 11 #define BUZZ 13 // Buzzer is connected to digital output 13. OneWire ds(12); // The DS18S20 is on digital output 12 // Global variables ----------------------------------------------------------------------- // Initialize an array with all 8 leds and give them the corresponding // digital number. const char led[8] = {0,1,2,3,4,5,6,7}; char state = ON; // This tells us if the light is ON or OFF char next = -1; // This indicates which LED we are on, in this case all off char dir = 'R'; // The direction where the light is going next, R for right, L for left char mode = 'C'; // The mode for the LEDs, C for chaser, T for temperature //------------------------------------------------------------------------------------------ // Function declarations ----------------------------------------------------------------- void blinker (void); // Rotates the LEDs void buttons (void); // Reads the buttons void melody_1 (void); // Calls for melody one void melody_2 (void); // Calls for melody two void temperature_read (void); // Reads temperature and displays in binary to the LEDs //----------------------------------------------------------------------------------------- // Melodys -------------------------------------------------------------------------------- //---------------- MELODY ONE ------------------------------------------------ // Notes in the melody: int melody1[] = {NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4}; // Note durations: 4 = quarter note, 8 = eighth note, etc.: int noteDurations1[] = {4,8,8,4,4,4,4,4}; //---------------- MELODY TWO ------------------------------------------------ // Notes in the melody: int melody2[] = {NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4, NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_F4, NOTE_C4, NOTE_C4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_AS4, NOTE_AS4, NOTE_A4, NOTE_F4, NOTE_G4, NOTE_F4}; // Note durations: 4 = quarter note, 8 = eighth note, etc.: int noteDurations2[] = {6, 6, 3, 3, 3, 3, 6, 6, 3, 3, 3, 3, 6, 6, 3, 3, 3, 3, 3, 6, 6, 3, 3, 3, 3}; //----------------------------------------------------------------------------------------- // Setup the system ------------------------------------------------------------- void setup() { // Initialize all 8 digital I/O pins as outputs. for (int i = 0; i<8; i++) { pinMode(led[i], OUTPUT); } // Initialize all 4 Switches as inputs. for (int i = 8; i<=11; i++) { pinMode(i, INPUT); } // Initialize Buzzer as output. pinMode(BUZZ, OUTPUT); // initialize timer1 --------------------------------------- noInterrupts(); // disable all interrupts TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; OCR1A = 9000; // Load value to compare TCCR1B |= (1 << WGM12); // CTC mode TCCR1B |= (1 << CS10); // 64 prescaler TCCR1B |= (1 << CS11); // TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt interrupts(); // enable all interrupts // ---------------------------------------------------------- } //--------------------------------------------------------------------------------- // Timer compare interrupt service routine -------------------------- ISR(TIMER1_COMPA_vect) // Here we chose between the blinker sequence { // or to show the temperature on the LEDs if (mode == 'C') { blinker(); } else { temperature_read(); } } // ------------------------------------------------------------------- // Main routine ----------------------------------- void loop() { // Turn off all digital I/Os, just to make sure for (int i = 0; i<14; i++) { digitalWrite(i, LOW); } while(1) { buttons(); // Forever check which button was pressed } } // ------------------------------------------------- void buttons (void) { // If button 1 was pressed change the register mode to 'C' // this will start the LED light sequence if (!digitalRead(BUTTON_1)) { mode = 'C'; } // If button 2 was pressed change the register mode to 'T' // this will start temperature reading if (!digitalRead(BUTTON_2)) { mode = 'T'; } // If button 3 was pressed call the funtion for melody 2 if (!digitalRead(BUTTON_3)) { melody_2(); while (!digitalRead(BUTTON_3)); // Check if button still pressed do nothing } // If button 4 was pressed call the funtion for melody 1 if (!digitalRead(BUTTON_4)) { melody_1(); } while (!digitalRead(BUTTON_4)); // Check if button still pressed do nothing } void blinker (void) { if (next == 7 && dir == 'R') { // If next LED is 7 and its rotating right dir = 'L'; // then set direction register (dir) to L left } else if (next == 0 && dir == 'L') { // If next LED is 0 and its rotating left dir = 'R'; // then set direction register (dir) to R right } if (state == OFF) { // If light state is OFF state = ON; // change light state to ON } else { // If light state is ON digitalWrite(next, LOW); // turn off next LED state = OFF; // change light state to OFF if (dir == 'R') { // If dir is set to 'R' right next++; // increment next } else { // if dir is set to 'L' left next--; // decrement next } digitalWrite(next, HIGH); // and turn ON next LED } } void melody_1 (void) // The following code and melody was taken { // from : http://arduino.cc/en/Tutorial/tone // iterate over the notes of the melody: for (int thisNote = 0; thisNote < BUZZ; thisNote++) { // to calculate the note duration, take one second // divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int noteDuration = 500/noteDurations1[thisNote]; tone(BUZZ, melody1[thisNote],noteDuration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.80; // originally 1.30 delay(pauseBetweenNotes); // stop the tone playing: noTone(BUZZ); } noTone(BUZZ); } void melody_2 (void) // The following code and melody was taken { // from : http://arduino.cc/en/Tutorial/tone // iterate over the notes of the melody: for (int thisNote = 0; thisNote < BUZZ; thisNote++) { // to calculate the note duration, take one second // divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int noteDuration = 500/noteDurations2[thisNote]; tone(BUZZ, melody2[thisNote],noteDuration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.30; // originally 1.30 delay(pauseBetweenNotes); // stop the tone playing: noTone(BUZZ); } noTone(BUZZ); } void temperature_read (void) { // This routine was directly take from the OneWire examples // library, please refer to : http://playground.arduino.cc/Learning/OneWire // and : http://www.pjrc.com/teensy/td_libs_OneWire.html byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; if ( !ds.search(addr)) { ds.reset_search(); return; } if (OneWire::crc8(addr, 7) != addr[7]) { return; } // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: type_s = 1; break; case 0x28: type_s = 0; break; case 0x22: type_s = 0; break; default: return; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // start conversion, with parasite power on at the end // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // "count remain" gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); // at lower res, the low bits are undefined, so let's zero them if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } raw = raw / 16; PORTD = raw; }