/* 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 , 02/12/2015 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 ----------------------------------------------------------------------- const int rot = A4; // Analog input pin to rotate leds const int vol = A5; // Analog input pin to simulate volume const char led[8] = {0,1,2,3,4,5,6,7}; // Start array with all 8 leds corresponding digital // number int sensorValue = 0; // value read from the pot char mode = 'V'; // The mode for: 'V' voltage, 'R' rotate, 'T' temperature //------------------------------------------------------------------------------------------ // Function declarations ----------------------------------------------------------------------- void VolumeLEDS (void); // Reads POT on A5, shows volume simulation acording to the value void RotateLEDS (void); // Reads POT on A4, rotates the leds acording to the value void melody (void); // Calls for melody one void temperature_read (void); // Reads temperature and displays it in binary to the LEDs //---------------------------------------------------------------------------------------------- //---------------- MELODY --------------------------------------------------------------- // 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}; //----------------------------------------------------------------------------------------- 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 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 check variable "mode" to find out // what funtion to run if (mode == 'R') { // R for rotate, V for volume, the rest for RotateLEDS(); // temperature reading } else if (mode == 'V') { VolumeLEDS(); } else { temperature_read (); } } // -------------------------------------------------------------------- void loop() { // If button 1 is pressed change the variable "mode" to 'T' // this will start reading temperature if (!digitalRead(BUTTON_1)) { mode = 'T'; } // If button 2 is pressed play melody if (!digitalRead(BUTTON_2)) { melody(); while (!digitalRead(BUTTON_2)); // Check if button is still pressed // do nothing } // If button 3 ispressed change the register "mode" to 'R' // this will start the leds rotating sequence if (!digitalRead(BUTTON_3)) { mode = 'R'; } // If button 4 ispressed change the register "mode" to 'V' // this will start the leds volume simulator if (!digitalRead(BUTTON_4)) { mode = 'V'; } } void RotateLEDS (void) { sensorValue = analogRead(rot); // read the analog value // from POT if (sensorValue < 128) { PORTD = 0x01; // Value to be displayed on leds } else if (sensorValue > 128 && sensorValue < 256) { PORTD = 0x02; } else if (sensorValue > 256 && sensorValue < 384) { PORTD = 0x04; } else if (sensorValue > 384 && sensorValue < 512) { PORTD = 0x08; } else if (sensorValue > 512 && sensorValue < 640) { PORTD = 0x10; } else if (sensorValue > 640 && sensorValue < 768) { PORTD = 0x20; } else if (sensorValue > 768 && sensorValue < 896) { PORTD = 0x40; } else { PORTD = 0x80; } // wait 60 milliseconds before the next loop // for the analog-to-digital converter to settle // after the last reading: delay(60); } void VolumeLEDS (void) { sensorValue = analogRead(vol); // read the analog value // from POT if (sensorValue < 128) { PORTD = 0xFF; // Value to be displayed on leds } else if (sensorValue > 128 && sensorValue < 256) { PORTD = 0xFE; } else if (sensorValue > 256 && sensorValue < 384) { PORTD = 0xFC; } else if (sensorValue > 384 && sensorValue < 512) { PORTD = 0xF8; } else if (sensorValue > 512 && sensorValue < 640) { PORTD = 0xF0; } else if (sensorValue > 640 && sensorValue < 768) { PORTD = 0xE0; } else if (sensorValue > 768 && sensorValue < 896) { PORTD = 0xC0; } else { PORTD = 0x80; } // wait 60 milliseconds before the next loop // for the analog-to-digital converter to settle // after the last reading: delay(60); } void melody (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); noTone(BUZZ); // stop the tone playing: } noTone(BUZZ); // stop the tone playing: } 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; }