297 lines
7.9 KiB
C++
297 lines
7.9 KiB
C++
/*
|
|
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 , 01/12/2015 V1.0
|
|
*/
|
|
#include "pitches.h"
|
|
#include <OneWire.h>
|
|
|
|
|
|
#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 = 0x80; // Value to be displayed on leds
|
|
}
|
|
else if (sensorValue > 128 && sensorValue < 256) {
|
|
PORTD = 0x40;
|
|
}
|
|
else if (sensorValue > 256 && sensorValue < 384) {
|
|
PORTD = 0x20;
|
|
}
|
|
else if (sensorValue > 384 && sensorValue < 512) {
|
|
PORTD = 0x10;
|
|
}
|
|
else if (sensorValue > 512 && sensorValue < 640) {
|
|
PORTD = 0x08;
|
|
}
|
|
else if (sensorValue > 640 && sensorValue < 768) {
|
|
PORTD = 0x04;
|
|
}
|
|
else if (sensorValue > 768 && sensorValue < 896) {
|
|
PORTD = 0x02;
|
|
}
|
|
else {
|
|
PORTD = 0x01;
|
|
}
|
|
|
|
// 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 = 0x80; // Value to be displayed on leds
|
|
}
|
|
else if (sensorValue > 128 && sensorValue < 256) {
|
|
PORTD = 0xC0;
|
|
}
|
|
else if (sensorValue > 256 && sensorValue < 384) {
|
|
PORTD = 0xE0;
|
|
}
|
|
else if (sensorValue > 384 && sensorValue < 512) {
|
|
PORTD = 0xF0;
|
|
}
|
|
else if (sensorValue > 512 && sensorValue < 640) {
|
|
PORTD = 0xF8;
|
|
}
|
|
else if (sensorValue > 640 && sensorValue < 768) {
|
|
PORTD = 0xFC;
|
|
}
|
|
else if (sensorValue > 768 && sensorValue < 896) {
|
|
PORTD = 0xFE;
|
|
}
|
|
else {
|
|
PORTD = 0xFF;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|