Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« on: June 01, 2011, 10:53:44 pm » |
I am missing something stupid here, I am using 3 cascaded CD4017 decade counters to feed ( up to ) 25 bcd switches. (I am posting here as it is multiplexing ) The 4 outputs of the switches are fed via diodes to 4 data inputs ( SW0 - 3 ) of the micro, each input has a pull down resistor. The following code is supposed to send the data from the switches via virtualwire , but with no connections to the data inputs - just the pull down resistors I get all 1000 when the ISR is triggered. i.e :- TX setup Sleep data for switchbank 0 = 1000 data for switchbank 1 = 1000 blah blah data for switchbank 18 = 1000 data for switchbank 19 = 1000 Sleep actually I think its trying to tell me something, its 4 am and I should have some rest  can anyone see my blonde moment here? Incidentally, with another chip for the scanning that has zero going outputs to the switches, I inverted the data with the commented out line // address |= digitalRead(SW ) << i; and this gives 1111 as expected...............
my code is
// FIRST TRY SCANNING USING 4017
#include <VirtualWire.h> // Wireless transmitter/receiver 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 = 3; // bits to read in unique address - LSB int SW1 = 4; // bits to read in unique address int SW2 = 5; // bits to read in unique address int SW3 = 6; // bits to read in unique address - MSB
int address = 0; int add0; int add1; int add2; int add3;
int reset = 7; int clock = 8;
int dpin0 = 0; // apparently redefined by Serial as Serial Monitor works int dpin1 = 1; // apparently redefined by Serial as Serial Monitor works int pin2 = 2; // Int0 interrupt pin
// create an array to store data to be sent out // *********************************************************************** int switchbanks = 19; // CHANGE TO NUMBER OF SWITCHES max 25 char msg [20]; // includes msg 0 which is PIN number from dip switches // ***********************************************************************
// * 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, LOW); 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 // Power up functions PRR = 0x00; /* First thing to do is disable sleep. */ sleep_disable(); }
// ***********************************************************************
void setup() {
Serial.begin(9600);
pinMode(pin2, INPUT); // our sleep interrupt pin digitalWrite(pin2, HIGH); // sets pull up res
pinMode ( reset, OUTPUT ); // resets the external cd4017 counters to 0 digitalWrite(reset, HIGH);
pinMode ( clock, OUTPUT ); // starts the clock to the CD4017s to zero so first out = PIN number digitalWrite(clock, LOW);
//***************************************************************************
// all data inputs SW0-3 have pull down 22k resistors pinMode(SW0, INPUT); // LSB of remote Address byte add0 = 0; pinMode(SW1, INPUT); // LSB+1 byte add1= 0; pinMode(SW2, INPUT); // LSB+2 byte add2 = 0; pinMode(SW3, INPUT); // MSB of address byte add3 = 0;
// ************************************************************************* Serial.begin(9600); Serial.println("TX setup"); // for debug only
// ***********************************************************************t // Initialise the IO and ISR for VirtualWire
vw_set_ptt_pin(10); // should be set as default ? vw_setup(4000); // Bits per sec
} // end of void Setup()
// *******************************************************************************************
void loop() { digitalWrite(reset, HIGH);
Serial.println("Sleep"); // for debug only enterSleep(); // call Sleep function to put us out // THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep() digitalWrite(reset, LOW);
scan ();
vw_send((uint8_t *)msg, switchbanks); // send the character out vw_wait_tx(); // Wait until the whole message is gone delay (10); } // end of void loop
//******************************************************************************************** void scan () { for ( int x=0; x<= switchbanks; x++ ) { digitalWrite(clock, LOW ); delay ( 50 ); address=0; for (uint8_t i = 0; i < 4; i++) { // read inputs from bcd switches sequenced by CD4017s // address |= digitalRead(SW[i]) << i; address = digitalRead(SW[i]) << i; } digitalWrite(clock, HIGH); // advances CD4017s ready for next read Serial.print("data for switchbank "); Serial.print(x); Serial.print(" = "); Serial.println(address, BIN); msg [switchbanks] = address;
} // end of for ( int x=2; x<= switchbanks; x==)
} // end of scan function
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Global Moderator
Boston area, metrowest
Offline
Brattain Member
Karma: 249
Posts: 16571
Available for Design & Build services
|
 |
« Reply #1 on: June 01, 2011, 11:22:41 pm » |
John, Can you post a schematic? Kinda late here, I am not seeing what the diodes are doing for you; somehow providing isolation between the switches? And what are the counters doing? Bob
This line: vw_setup(4000); // Bits per sec I had to use 4000 with my 8MHz Promini running at 3.7V for this to look like 2000 to a 16 MHz Promini at 5V. What speeds are you running?
These lines: int add0; int add1; int add2; int add3;
You then go on to call them bytes in Setup; you can probably ditch these also.
|
|
|
|
|
Logged
|
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #2 on: June 02, 2011, 02:47:46 am » |
Hi Robert here's a link to the basic cct for one CD4017 giving 10 switches. I cant just add the picture as it looks like flikr wants people to go there and look..... I am using a 16M xtal, and the 4000 baudrate seems to be working fine on all the other projects ( though I slow it to 2400 for the new cheapy transmit / receive pair I have been experimenting with ) http://flic.kr/p/9PB8nm
|
|
|
|
« Last Edit: June 02, 2011, 02:53:23 am by Boffin1 »
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Manchester (England England)
Online
Brattain Member
Karma: 277
Posts: 25562
Solder is electric glue
|
 |
« Reply #3 on: June 02, 2011, 03:02:53 am » |
The 4017 is the wrong chip to use here. You need a signal that has only one pin high with all the others low. I can't see all the code at e moment as my iPad doesn't do the scrolling boxes correctly so I can't be sure but it looks like you are addressing all the switches at once. Put them all to 8, is there any difference?
|
|
|
|
|
Logged
|
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #4 on: June 02, 2011, 03:12:15 am » |
Hi Mike
The outputs of the 4017 have only one high at a time, each output goes to the common of a bcd thumbwheel switch, the 4 switched outputs of the switches have steering diodes so that they don't short out the 4 data lines. I have used this circuit extensively, but with a cd4514 chip to feed the switches, but that would need 2 of them to do 32 switches, and take 5 pins of the micro for their bcd address, so I want to try it this way with just 2 pins to control as many switches as I like ( I am keeping it down to 25 switches as thats all that the 4017 can cascade, and the VirtualWire can handle only 27 messages.
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Manchester (England England)
Online
Brattain Member
Karma: 277
Posts: 25562
Solder is electric glue
|
 |
« Reply #5 on: June 02, 2011, 07:20:17 am » |
I think this bit is wrong:- address = digitalRead(SW) << i; You have commented out // address |= digitalRead(SW) << i; Which is closer I would put:- address |= ( ( digitalRead(SW) & 0x1) << i);
|
|
|
|
|
Logged
|
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #6 on: June 02, 2011, 07:57:06 am » |
Thanks
I will play around with that and actually hook up a bcd switch to see whats happening.
It seemed to be working with the commented out bit, but of course inverted ( 1111 for all switches off ) but I can always invert it at the RX end anyway.
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #7 on: June 02, 2011, 08:18:06 am » |
when I try that I get:-
invalid conversion from 'uint8_t*'to 'uint8_t'
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #8 on: June 02, 2011, 09:03:55 am » |
Now I am really confused, when I connect a binary switch, the data stays the same, and also the clock signal doesnt change....
I think I must strip it down to bare bones and try it
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #9 on: June 03, 2011, 10:51:58 am » |
OK, with hindsight and a couple of hours sleep I sorted out why I was getting 1000 reading from the switches when scanned - one of the pull-down resistor leads had become open circuit ( read bad soldering by me )
But meantime I still had to go back to the longer "or" ing each bit to get it to work for some reason.
What does " invalid conversion from 'uint8_t*'to 'uint8_t' " mean?
is the * a pointer ? or should I leave that closet closed until I have time to learn more?
The reason I want to only have two micro pins controlling the CD4017 counting, is that I want to later use another 7 pins for a 3x4 keyboard.
I should still have some spare pins for flexibility.
I hope to be able to send in one packet :- the selected decimal number from up to 25 BCD switches, and one of 12 keypresses, plus a security number ( which I call PIN ) all in one 27 byte burst using VirtualWire.
Tonight I am on the receiver decoder, I love VirtualWire, with literally one wire ( the usb plugs do the ground ) I don't have to run the RF link for testing, which is a blessing for all my neighbours who are trying to open the complex gate with their remotes ( also on 433 Mhz )
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Manchester (England England)
Online
Brattain Member
Karma: 277
Posts: 25562
Solder is electric glue
|
 |
« Reply #10 on: June 03, 2011, 02:00:16 pm » |
Sorry I didn't use the # icon and the board scrambled my code, what I put was:- address |= ( ( digitalRead(SW[i]) & 0x1) << i); As posted you were using an array without an in index, hence the pointer error message.
|
|
|
|
|
Logged
|
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #11 on: June 03, 2011, 04:13:48 pm » |
Thanks Mike I will try that. I have got the receiver listing all 19 switches, plus the PIN nunmber checking, next stage is to build it on veroboard, and shiftout to 19 displays. I know shiftout is not that fast, but this project is to replace the Holtek chips I was using that took about 2 seconds to update.
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #12 on: June 09, 2011, 05:51:26 pm » |
OK I finally got the 25 BCD switch scanner going, I am only using 19 switches for this project, see photo http://flic.kr/p/9RWEo6 of the test setup ( and the remote control box with all its filed rectangular holes and half the wiring done.) I am using an Arduino board ( top right ) with only 3 switches connected to test it. The receiver has only little 3 displays for testing. The 19 chips are TPIC6B595 daisychained shift registers with high current sinking for large common anode LED displays The 3 x CD4017 decade counters are on the vero/perf board in the middle of the pic, they are cascaded to give up to 25 outputs to the switchbanks. I am running the RF link at 2400 , and all 19 displays update in less than half a second . Hopefully I can get it all boxed up by the weekend.
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #13 on: June 10, 2011, 03:22:45 am » |
Here's a link to the circuit of the 4017 cascade part of the circuit. I have used simple diode gating to save the AND gate suggested on the datasheet for cascading. http://flic.kr/p/9S6oUyI always use BAT85 schottky diodes as they only have about 250mV across them when on, as opposed to 650mV for a 1N4148. You can repeat the middle chip as many times as you want, getting 8 more outputs for every chip. I reset the chips with the first reset rather than the last 0 in the datasheet, so have 9 outputs from that chip as well. This gives 26 outputs, I am using the first ( 0 ) for the PIN number on my system, and the other 25 are available for the BCD switches.
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
Cape Town South Africa
Offline
Edison Member
Karma: 17
Posts: 1104
A newbie with loads of posts, and still so much to learn !
|
 |
« Reply #14 on: June 13, 2011, 06:34:37 am » |
I have everything working fine, the radio range is brilliant, I walked two blocks away and the signal got through 4 houses and about 200 meters before I couldn't walk any more ( a dead end road ) But now and again, when the system has been on a time and I have been randomly checking it, It throws up a wrong display, sometimes all the displays go off and when I checked the Tx, I found that it was just sending zeros. It is very intermittent though. most times its fine. Is there anything in the code below that might be filling up some memory or whatever ? I am basically scanning the outputs of the 4017 to read 20 bcd switches, as in the sketch linked in a message above, and transmitting it via VirtualWire.... // FIRST TRY SCANNING USING 4017 serialprints commented out to speed up
#include <VirtualWire.h> // Wireless transmitter/receiver 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 = 3; // bits to read in unique address - LSB int SW1 = 4; // bits to read in unique address int SW2 = 5; // bits to read in unique address int SW3 = 6; // bits to read in unique address - MSB int address = 0;
int reset = 18; int clock = 16; int pwrup = 19; // for powering cd4017 counters, left hi in this example
int dpin0 = 0; // apparently redefined by Serial as Serial Monitor works int dpin1 = 1; // apparently redefined by Serial as Serial Monitor works int pin2 = 2; // Int0 interrupt pin
// create an array to store data to be sent out // *********************************************************************** int switchbanks = 20; // CHANGE TO NUMBER OF SWITCHES +1 for pin dipswitch max 25 char msg [20]; // includes msg 0 which is PIN number from dip switches // ***********************************************************************
// * Name: pin2Interrupt, "ISR" to run when interrupted in Sleep Mode void pin2Interrupt() { /* This brings us back from sleep. */ } // ******************************************************************** 66 void enterSleep() { attachInterrupt(0, pin2Interrupt, LOW); 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 // Power up functions PRR = 0x00;
sleep_disable(); /* First thing to do is disable sleep. */ }
// ***********************************************************************
void setup() { Serial.begin(9600); pinMode(pin2, INPUT); // sleep interrupt pin digitalWrite(pin2, HIGH); // sets pull up res
pinMode ( clock, OUTPUT ); // starts the clock to the CD4017s to zero so first out = PIN number digitalWrite(clock, LOW); pinMode ( reset, OUTPUT ); // resets the external cd4017 counters to 0 digitalWrite(reset, HIGH);
pinMode ( pwrup, OUTPUT ); digitalWrite(pwrup, HIGH); // leave high for testing //***************************************************************************
// all data inputs SW0-3 have pull down 22k resistors pinMode(SW0, INPUT); // LSB of remote Address byte add0 = 0; pinMode(SW1, INPUT); // LSB+1 byte add1= 0; pinMode(SW2, INPUT); // LSB+2 byte add2 = 0; pinMode(SW3, INPUT); // MSB of address byte add3 = 0;
// ************************************************************************* Serial.begin(9600); Serial.println("TX setup"); // for debug only
// ***********************************************************************t // Initialise the IO and ISR for VirtualWire vw_set_tx_pin(9); vw_set_ptt_pin(11); // should be set as default ? vw_setup(2400); // Bits per sec
} // end of void Setup()
// *******************************************************************************************
void loop() { digitalWrite(reset, HIGH); Serial.println("Sleep"); // for debug only enterSleep(); // call Sleep function to put us out // THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep() digitalWrite(reset, LOW);
scan ();
vw_send((uint8_t *)msg, switchbanks); // send the character out vw_wait_tx(); // Wait until the whole message is gone } // end of void loop
//******************************************************************************************** void scan () { for ( int r=0; r<= switchbanks; r++ ) { digitalWrite(clock, LOW );
address=0;
add3 = digitalRead(SW3); add3 = add3 << 3; add2 = digitalRead(SW2); add2 = add2 << 2; add1 = digitalRead(SW1); add1 = add1 << 1; add0 = digitalRead(SW0); // now OR it together address = address|add3; address = address|add2; address = address|add1; address = address|add0; msg [r] = address;
digitalWrite(clock, HIGH ); // move 4017 on to next switch delay ( 20 ); } // end of for ( int x=2; x<= switchbanks; x==) } // end of scan function
|
|
|
|
|
Logged
|
We live in the era of the smart phones and stupid people.
|
|
|
|
|