Pages: [1] 2   Go Down
Author Topic: scanning 25 bcd switches - wrong reading?  (Read 2173 times)
0 Members and 1 Guest are viewing this topic.
Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley-roll-sweat
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
Code:
//  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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 545
Posts: 27361
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Manchester (England England)
Online Online
Brattain Member
*****
Karma: 634
Posts: 34553
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Manchester (England England)
Online Online
Brattain Member
*****
Karma: 634
Posts: 34553
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

when I try that I get:-

invalid conversion from 'uint8_t*'to 'uint8_t'



Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Manchester (England England)
Online Online
Brattain Member
*****
Karma: 634
Posts: 34553
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry I didn't use the # icon and the board scrambled my code, what I put was:-
Code:
      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 Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset



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/9S6oUy

I 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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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....


Code:
//  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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Pages: [1] 2   Go Up
Jump to: