Decimal to BCD on digital pins?

Happy new years all :slight_smile:

I could use a little guidance on how to tighten up some code.
Basically i will be using 8 digital output pins on an arduino nano and two 4028's (BCD to Decimal ic's) to poll multiple ultrasonic sensors at specific timings to avoid cross talk.

The table below translates the pin states on the two ic's and the subsequent output (relavant to a given sensor) of the 4028s.

In setup i have made it easy to recall the relevant binary functions (in the program loop) on the Arduinos outputs. This is to makes it easy to modify according to the environment and the position of the sensors to one another (which is not finalised yet and of which I may have little control over).

However, it makes the set up very long winded (stacks of on/off functions), and whilst i know so little about code (this is my first program) and am new to working with binary. Im guessing there is a more efficient way to do this (translating the decimals to binary and assigning the result to output to pins?) and would appreciate any input.

bellow is the current code and a small example loop to help explain the idea and what I will be doing is trying to cram as much polling as possible in, in as little time as possible.

/*
  DECIMAL TO BCD PINS
  IC1
  1 = 2
  2 = 3
  3 = 3 & 2
  4 = 4
  5 = 4 & 2
  6 = 4 & 3
  7 = 4 & 3 & 2
  8 = 5
  IC2
  9 = 5 & 2
  10 = 6
  11 = 7
  12 = 7 & 6
  13 = 8
  14 = 8 & 6
  15 = 8 & 7
  16 = 8 & 7 & 6
  17 = 9
  18 = 9 & 6
*/

//IMPORTANT TEST POLLING DELAY REQUIRED FOR A SINGLE CHIP

int on = 1;
int off = 20;

void setup()
{
  pinMode(2, OUTPUT); // IC a 1-9
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT); //IC b 10-18
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);

  pinMode(13, OUTPUT); // test pin
}

// POLL ON
void poll_1on() {
  digitalWrite(2, HIGH);
}
void poll_2on() {
  digitalWrite(3, HIGH);
}
void poll_3on() {
  digitalWrite(3, HIGH);
  digitalWrite(2, HIGH);
}
void poll_4on() {
  digitalWrite(4, HIGH);
}
void poll_5on() {
  digitalWrite(4, HIGH);
  digitalWrite(2, HIGH);
}
void poll_6on() {
  digitalWrite(4, HIGH);
  digitalWrite(3, HIGH);
}
void poll_7on() {
  digitalWrite(4, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(2, HIGH);
}
void poll_8on() {
  digitalWrite(5, HIGH);
}
void poll_9on() {
  digitalWrite(5, HIGH);
  digitalWrite(2, HIGH);
}
void poll_10on() {
  digitalWrite(6, HIGH);
}
void poll_11on() {
  digitalWrite(7, HIGH);
}
void poll_12on() {
  digitalWrite(7, HIGH);
  digitalWrite(6, HIGH);
}
void poll_13on() {
  digitalWrite(8, HIGH);
}
void poll_14on() {
  digitalWrite(8, HIGH);
  digitalWrite(6, HIGH);
}
void poll_15on() {
  digitalWrite(8, HIGH);
  digitalWrite(7, HIGH);
}
void poll_16on() {
  digitalWrite(8, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(6, HIGH);
}
void poll_17on() {
  digitalWrite(9, HIGH);
}
void poll_18on() {
  digitalWrite(9, HIGH);
  digitalWrite(6, HIGH);
}

// POLL OFF
void poll_1off() {
  digitalWrite(2, LOW);
}
void poll_2off() {
  digitalWrite(3, LOW);
}
void poll_3off() {
  digitalWrite(3, LOW);
  digitalWrite(2, LOW);
}
void poll_4off() {
  digitalWrite(4, LOW);
}
void poll_5off() {
  digitalWrite(4, LOW);
  digitalWrite(2, LOW);
}
void poll_6off() {
  digitalWrite(4, LOW);
  digitalWrite(3, LOW);
}
void poll_7off() {
  digitalWrite(4, LOW);
  digitalWrite(3, LOW);
  digitalWrite(2, LOW);
}
void poll_8off() {
  digitalWrite(5, LOW);
}
void poll_9off() {
  digitalWrite(5, LOW);
  digitalWrite(2, LOW);
}
void poll_10off() {
  digitalWrite(6, LOW);
}
void poll_11off() {
  digitalWrite(7, LOW);
}
void poll_12off() {
  digitalWrite(7, LOW);
  digitalWrite(6, LOW);
}
void poll_13off() {
  digitalWrite(8, LOW);
}
void poll_14off() {
  digitalWrite(8, LOW);
  digitalWrite(6, LOW);
}
void poll_15off() {
  digitalWrite(8, HIGH);
  digitalWrite(7, HIGH);
}
void poll_16off() {
  digitalWrite(8, LOW);
  digitalWrite(7, LOW);
  digitalWrite(6, LOW);
}
void poll_17off() {
  digitalWrite(9, LOW);
}
void poll_18off() {
  digitalWrite(9, LOW);
  digitalWrite(6, LOW);
}




void poll_teston() // TEST PIN FOR CHECKING CODE
  {
  digitalWrite(13, HIGH);
  }

  void poll_testoff()
  {
  digitalWrite(13, LOW);
  }


void loop()
/*{
  poll_teston(); // TEST PIN EXAMPLE CODE
  delay(on);
  poll_testoff();
  delay(off);
  }
*/

//IMPORTANT TEST POLLING DELAY REQUIRED FOR A SINGLE CHIP 1-8 9-18
// delayMicroseconds(200); for delays in polling on a single 4028

{
  poll_1on();
  delayMicroseconds(200);
  poll_3on(); 
  delay(on);
  poll_1off();
  delayMicroseconds(200);
  poll_3off();
  delay(off);

  poll_2on();
  poll_13on(); 
  delay(on);
  poll_2off();
  poll_13off();
  delay(off);

 
}

Define an array of the different states required for the polling, then use a loop to index through the array to poll.

Example code (not tested and not same as your states, just to show the idea)

const uint8_t MAX_STATES = <put the number here>;

uint8_t pollStates[MAX_STATES] = { 2, 3, 5, etc };

loop()
{
  for (uint8_t i=0; i<MAX_STATES; i++)
  {
     // do the stuff you need here
  }
}

In order to turn the bits on and off, you just need to build some logic that will check each bit and turn on or off as required. Something like

if (value & 0b00000001)  // check first bit
  digitalWrite(1, ON);
else
  digitalWrite(1, OFF);
// etc for the other bits

this can be made shorter like this, using the ternary operator '?'

  digitalWrite(1, value & 0b00000001 ? ON : OFF);
  digitalWrite(1, ON);

Where are ON and OFF defined?

Brain snap, should be LOW and HIGH...

Thanks marco, my heads a little broken at this point, i think im following the logic. Will sit down and try and apply it and get back with questions tomorrow.

Again thanks for a quick response :slight_smile:

Really, this should be done with a write using direct port manipulation. It would eliminate all the bit fiddling.

You could consider using SPI and 74LS595

aarg:
Really, this should be done with a write using direct port manipulation. It would eliminate all the bit fiddling.

Interesting, unless im missing something this has been the most easiest thing i have learnt so far.

so my former code would essentially be this?

int on = 1;
int off = 20;

void setup()
//ic1 port D 0-7 pins 2,3,4,5
//ic2 port B 8-13 pins 8,9,10,11
{
  DDRD = B00111100;  // sets pins 2-5 as outputs,
  DDRB = B001111; // sets pins 8-11 as outputs
}


void loop()

//IMPORTANT TEST POLLING DELAY REQUIRED FOR A SINGLE CHIP 1-8 9-18
// delayMicroseconds(200); for delays in polling on a single 4028

{
  PORTD = B00000100; //1
  delayMicroseconds(200);
  PORTD = B00001100; //3
  delay(on);
  PORTD = B00000000; // Port D off
  delay(off);

  PORTD = B00001000; //2
  PORTB = B000100; //13
  delay(on);
  PORTD = B00000000; // Port D off
  PORTB = B000000; //Port B off
  delay(off);

// And so on and so on...
}

/*
  PORTD = B00000100; //1
  PORTD = B00001000; //2
  PORTD = B00001100; //3
  PORTD = B00010000; //4
  PORTD = B00010100; //5
  PORTD = B00011000; //6
  PORTD = B00011100; //7
  PORTD = B00100000; //8
  PORTD = B00100100; //9
  PORTB = B000001; //10
  PORTB = B000010; //11
  PORTB = B000011; //12
  PORTB = B000100; //13
  PORTB = B000101; //14
  PORTB = B000110; //15
  PORTB = B000111; //16
  PORTB = B001000; //17
  PORTB = B001001; //18

  PORTD = B00000000; // Port D off
  PORTB = B000000; //Port B off


*/

edit:

LarryD:
You could consider using SPI and 74LS595

Thanks larry, will look into this too, along with marcos idea. More i can get my head around the better.

Verify the table

9 8 7 6   5 4 3 2
------- | --------
0 0 0 0 | 0 0 0 0   |  0
0 0 0 0 | 0 0 0 1   |  1
0 0 0 0 | 0 0 1 0   |  2
0 0 0 0 | 0 0 1 1   |  3
0 0 0 0 | 0 1 0 0   |  4
0 0 0 0 | 0 1 0 1   |  5
0 0 0 0 | 0 1 1 0   |  6
0 0 0 0 | 0 1 1 1   |  7
0 0 0 0 | 1 0 0 0   |  8
0 0 0 0 | 1 0 0 1   |  9
0 0 0 1 | 0 0 0 0   | 10
0 0 1 0 | 0 0 0 0   | 11
0 0 1 1 | 0 0 0 0   | 12
0 1 0 0 | 0 0 0 0   | 13
0 1 0 1 | 0 0 0 0   | 14
0 1 1 0 | 0 0 0 0   | 15
0 1 1 1 | 0 0 0 0   | 16
1 0 0 0 | 0 0 0 0   | 17
1 0 0 1 | 0 0 0 0   | 18

If accurate

#define COUNT_ENTRIES(ARRAY)    (sizeof(ARRAY) / sizeof(ARRAY[0]))

const uint8_t   pins[]  = { 2, 3, 4, 5, 6, 7, 8, 9 };

const uint8_t   table[] =
{
      b00000000 //  0
    , b00000001 //  1
    , b00000010 //  2
    , b00000011 //  3
    , b00000100 //  4
    , b00000101 //  5
    , b00000110 //  6
    , b00000111 //  7
    , b00001000 //  8
    , b00001001 //  9
    , b00010000 // 10
    , b00100000 // 11
    , b00110000 // 12
    , b01000000 // 13
    , b01010000 // 14
    , b01100000 // 15
    , b01110000 // 16
    , b10000000 // 17
    , b10010000 // 18
};

void setBCD(uint8_t value)
{
    for ( size_t i = 0; i < COUNT_ENTRIES(pins); value >>= 1, i++ )
    {
        digitalWrite(pins[i], ((value & 1) ? HIGH : LOW))
    }
}

Yes, and that big list could be put in an array and sent out also.