I have made several remote controls that scan thumbwheel BCD switches, and some push-buttons arranged as a keypad, but this one has me scratching my head.
One of the thumbwheel switches will not show the number 7 ! it shows 0. It will show 0,1,2,3,4,5,6,8,9 but not 7.
I have attached a circuit diagram / schematic which shows the basic arrangement.
The chip is normally in sleep mode, and when any of the keys are pressed, it wakes up and reads which key character, then scans 7 pins connected to the commons of the thumbwheel switches , which feeds 5v via diodes ( 4 each bcd switch ) to 4 input pins to monitor the 1-2-4-8 lines from the switches.
It then sends msg[0] which is an unique address code I call PIN, then msg[1] which is the character for which key was pressed, and then the 7 integers representing the numbers dialled on each switch.
Everything works fine unless I have a 7 set on switch 8, it is not the switch as I can swap the common wires and it is now switch 7 that doesn't show 7 ( and switch 8 does )
Any clues ? it is usually my silly error but I have looked through this many times, and rewired it with different pins.
#include <VirtualWire.h> // Wireless transmitter/receiver library
#include <Keypad.h> // Matrix Keypad library
#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library
uint8_t SW[4]; // assign four data pins from bcd switches
int SW0 = 5; // bits to read from bcd switches LSB
int SW1 = 6;
int SW2 = 7;
int SW3 = 8; // - MSB
int address = 0;
int add0; // bits generated from cd switches
int add1;
int add2;
int add3;
int comA = 3; // switch scans to swithch sliders
int comB = 4;
int comC = 11;
int comD = 12;
int comE = 13; // for period
int comF = 14;
int comG = 15;
int PIN = 74; // unique for this display
int dpin0 = 0;
int dpin1 = 1;
int pin2 = 2;
// create an array to store data to be sent out
char msg [9]; // pin, key, A,B,C,D,E,F,G
// set up the Keypad
const byte ROWS = 2; // two rows
const byte COLS = 3; // three columns
// Define the Keymap
char keys[ROWS][COLS] =
{
{
'A','B' }
, // row 1 //
{
'D','C' , 'E' }
, // row 2
};
byte rowPins[ROWS] = {
9,17 }; // Keypad uses internal pullups? No externals supplied
// Pressing a Row button connects to a Low Columna and pulls the
//appropriate Row Diode Low for a Pin2 Low interrupt.
// Column pins are then set back high for the keypad library button determination.
byte colPins[COLS] = {
16, 19, 18};
// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
//***************************************************
// * Name: pin2Interrupt, "ISR" to run when interrupted in Sleep Mode
void pin2Interrupt()
{
/* This brings us back from sleep. */
}
//***************************************************
// * Name: enterSleep
void enterSleep()
{
/* Setup pin2 as an interrupt and attach handler. */
attachInterrupt(0, pin2Interrupt, FALLING);
delay(50); // need this?
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setting up for sleep ...
sleep_enable(); // setting up for sleep ...
ADCSRA &= ~(1 << ADEN);
PRR = 0xFF;
sleep_mode(); // now goes to Sleep and waits for the interrupt
/* The program will continue from here after the interrupt. */
detachInterrupt(0); //disable interrupts while we get ready to read the keypad
PRR = 0x00;
/* First thing to do is disable sleep. */
sleep_disable();
// set all the keypad columns back high so can read keypad presses again
digitalWrite(16, HIGH);
digitalWrite(19, HIGH);
digitalWrite(18, HIGH);
// then go to the void Loop()
}
//************************************************************************** LOOP
void setup()
{
Serial.begin(9600);
/* Setup the pin directions, write inputs High to turn on internal pullups */
Serial.println("my address is: ");
pinMode(pin2, INPUT); // our sleep interrupt pin
digitalWrite(pin2, HIGH); // set pull up res
pinMode(dpin0, INPUT);
digitalWrite(dpin0, HIGH);
pinMode(dpin1, INPUT);
digitalWrite(dpin1, HIGH);
pinMode (comA , OUTPUT ); // common slders of the BCD switches
pinMode (comB , OUTPUT );
pinMode (comC , OUTPUT );
pinMode (comD , OUTPUT );
pinMode (comE , OUTPUT );
pinMode (comF , OUTPUT );
pinMode (comG , OUTPUT );
pinMode(SW0, INPUT); // LSB of bcd
byte add0 = 0;
pinMode(SW1, INPUT); // LSB+1
byte add1= 0;
pinMode(SW2, INPUT); // LSB+2
byte add2 = 0;
pinMode(SW3, INPUT); // MSB of bcd
byte add3 = 0;
Serial.println("my address is: "); Serial.println(int (PIN));
digitalWrite(SW0, LOW); // disable pullups on PIN inputs to save current
digitalWrite(SW1, LOW);
digitalWrite(SW2, LOW);
digitalWrite(SW3, LOW);
Serial.println("TX setup");
vw_set_tx_pin(10);
vw_setup(2000);
}
// ************************************************end of void Setup()
void loop()
{
Serial.println("Sleep"); // for debug only
digitalWrite(19,LOW);
digitalWrite(16, LOW);
digitalWrite(18, LOW);
enterSleep(); // call Sleep function to put us out
// THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep()
char key = keypad.getKey(); // reading the keypad
if(key) {
msg[1] = key;
}
Serial.print("key read =");
Serial.println(int (key));
msg [0] = PIN;
digitalWrite(comA, LOW); // make sure all commons low
digitalWrite(comB, LOW);
digitalWrite(comC, LOW);
digitalWrite(comD, LOW);
digitalWrite(comE, LOW);
digitalWrite(comF, LOW);
digitalWrite(comG, LOW);
//****************************** NOW TAKE EACH COM HIGH AND READ THE SWITCHES
digitalWrite(comA, HIGH);
scan ();
msg [3] = address;
digitalWrite(comA, LOW);
//***********************************
digitalWrite(comB, HIGH);
scan ();
msg [2] = address;
digitalWrite(comB, LOW);
//***********************************
digitalWrite(comC, HIGH);
scan ();
msg [8] = address;
Serial.print(", address in 8 scan = "); Serial.println(int (address));
digitalWrite(comC, LOW);
//***********************************
digitalWrite(comD, HIGH);
scan ();
msg [7] = address;
digitalWrite(comD, LOW);
//***********************************
digitalWrite(comE, HIGH);
scan ();
msg [6] = address;
digitalWrite(comE, LOW);
//***********************************
digitalWrite(comF, HIGH);
scan ();
msg [5] = address;
digitalWrite(comF, LOW);
//***********************************
digitalWrite(comG, HIGH);
scan ();
msg [4] = address;
digitalWrite(comG, LOW);
//***********************************
vw_send((uint8_t *)msg, 9); // send the character out
vw_wait_tx(); // Wait until the whole message is gone
} // end of void loop
//------------------------------------------------------------
void scan ()
{
address=0;
add3 = digitalRead(SW3);
add3 = add3 << 3;
add2 = digitalRead(SW2);
add2 = add2 << 2;
add1 = digitalRead(SW1);
add1 = add1 << 1;
add0 = digitalRead(SW0);
address = address|add3;
address = address|add2;
address = address|add1;
address = address|add0;
}