i would like to convert some code into some signals

Status
Not open for further replies.

nagual

Well-known member
greetings,

I want a piece of code that looks like "0x1F" to be sent to 8 different output pins, each representing a place in the binary number that "0x1F" is presumed to represent.

to rephrase for clarity,

I want to make a physical 'copy' of a binary value manifest itself in the electrical charge state of 8 (digital) pins, so if i had 8 LEDs, they would light up and represent the binary value of whatever 8 bit hex number was fed into it.

I don't want to use the port feature or any of that, i want to just build the code from scratch, like one wire going to the next wire, but i need to build a little process that accepts a hex value and emits a binary number, and another process to divide that binary number into 8 pieces, and assigns them one at a time to a respective output pin on the Teensy 3.1. I will assign them arbitrarily to any sequence of digital pins I choose, I will not subscribe to the superstition that they need to be wired in special order to do simple things like turn on and off leds for example.

i want to ignore weird things like ports and such. i want to understand this before i rely on other code that creates compounding obscurity at my skill level. i need to understand one thing before i can understand the next thing, i can't keep on replacing variables with other variables.

so, to reiterate, a hex value that looks like "0xF1" i want to convert to its full 8 bit binary equivalent in zeroes and ones, chop those zeroes and ones into 8 pieces, and send each piece in order, to deliver electrical charges on a Teensy's output pins.

I hope this was a good explanation of my problem of which i have no solution.
 
Last edited:
No ports just extracting bits .

First the logic:
On one hand "0xF1" is a 8 bit binary expression, written in hexadecimal form. But the problem is to extract the binary bits
as 8 individual bit values. Mathematically its clear 0xF1 hexadecimal is 11110001 binary 15*16+1 decimal.
So the bits are, usually numbered from 0 up to 7 in programming circles. b0 = 1, b1 = 0, b2 = 0, b3 = 0, b4 = 1, b5 = 1,
b6 = 1 and finally b7 = 1. So the bits are numbered b7 b6 b5 b4 b3 b2 b1 b0 , just like we put thousands before hundreds
before tens before ones.

Next problem, how do we extract the bits from a variable in code:

uint8_t value = 0xF1; /* an 8 bit number */
uint8_t b0 = value&0x1; /* The & operator is bitwise and, so we test if bit 0 is 1 */
uint8_t b1 = (value&0x2) != 0; /* The value of bit 2 is 2, so we thake the bitwise and with 2 and check if its non zero */
etc ...

Now this can be done in different ways

uint8_t b1 = (value>>1)&0x1; /* Shift the value one bit to the right and se if the result has a first bit different from 0 */

so on to next bit

uint8_t b2 = (value&0x4) != 0; /* or */
uint8_t b2 = (value>>2)&1; /* Shift the value two bits to the right and se if the result has a first bit different from 0 */
 
what about the assigning a voltage to a pin, what's the smallest bit of code to do that?

p=high; ?
 
Digital pins can be low or high, 0 volt low and 3.3 volt high for Teensy 3.1 and 5 volt high for some other chips.

You assign the output voltage to the pin by configuring the pin as output and then writing 0 or 1 to it.

pinMode(pinnumber, OUTPUT); /* Configure as output */

digitalWriteFast(pinnumber, 0); /* set pin low , 0volt */
digitalWriteFast(pinnumber, 1); /* set pin high , 3.3volt */

Perhaps now is the time to forget synth chips for a day or two, and work through some tutorials,
carefully working to understand whats happening.
 
..another way is to shift a constant (1) left instead of the value right. It's basically the same as mlus first variant but avoids hex values

uint8_t b0 = value & (1<<0); //shift "1" 0 times left (=0)
uint8_t b1 = value & (1<<1); //shift "1" 1 times left (=1)
uint8_t b2 = value & (1<<2); //shift "1" 2 times left (=2)
uint8_t b3 = value & (1<<3); //shift "1" 3 times left (=4)
uint8_t b4 = value & (1<<4); //shift "1" 4 times left (=8)
...
Perhaps it makes a bit more sense with the oposite way, e.g. if you want to set a value where the bits 3 & 4 are set:
uint8_t value = (1<<4) | (1<<3); // "|" means "or"
This is in some cases a bit better to understand than value = 0x18 or value = 24;

Edit (deleted wrong text...):
an other way is to use "if..else" :

if ( value & 0x1 == 0x1 ) {b0 = 1;} else {b0 = 0;}
if ( value & 0x2 == 0x2 ) {b1 = 1;} else {b1 = 0;}
if ( value & 0x4 == 0x4 ) {b2 = 1;} else {b2 = 0;}

A good book is http://www.amazon.de/The-Programmin...0-5437425?ie=UTF8&refRID=0BCYTTNC9NM6E754K4R7
 
Last edited:
Beg to disagree about comparisons:

uint8_t bn = (value>>n)&1

This is pure logical calculations, no comparison, no 'if' - 'else' no branch generated
 
Argh... OOpps.. YES, sorry. Of course you're right,
I take it all back. some how must have had your != 0 in mind, but wrong

and @nagual, know that "uint8_t b4 = value & (1<<4); //shift "1" 4 times left (=8)" will not be set to 0 or 1, it is 0 or 8 :)

its better to go to bed now. its 1 am here. :)

edit: Edited wrong text above...dont want to confuse...
 
Last edited:
It is a fairly simple loop, though you have to determine whether you want the first pin to be 0x80 or 0x01. Assume for the sake of argument you want the first pin to be 0x01, and you want to hold the digital pin numbers in an array for easier processing. The code would look like:

Code:
static const int pins[] = { 2, 3, 4, 5, 6, 7, 8, 9 10 };

void binary_to_signals (uint8_t value)
{
    for (int i = 0; i < 8; i++) {
        if ((value & (1 << i)) != 0) {
            digitalWrite (pin[i], HIGH);
        } else {
            digitalWrite (pin[i], LOW);
        }
    }
    return;
}

Now, you can simplify this to use the ?: operator in C/C++:

Code:
static const int pins[] = { 2, 3, 4, 5, 6, 7, 8, 9 10 };

void binary_to_signals (uint8_t value)
{
    for (int i = 0; i < 8; i++) {
        digitalWrite (pin[i], (value & (1 << i)) != 0 ? HIGH : LOW);
    }
    return;
}

And if the pins are sequential like in the above example, you can do it via:

Code:
const int FIRST_PIN = 2;

void binary_to_signals (uint8_t value)
{
    for (int i = 0; i < 8; i++) {
        digitalWrite (FIRST_PIN + i, (value & (1 << i)) != 0 ? HIGH : LOW);
    }
    return;
}

Now let's say that you want to go in reverse, you would change the shift count to be the modular opposite:

Code:
const int FIRST_PIN = 2;

void binary_to_signals (uint8_t value)
{
    for (int i = 0; i < 8; i++) {
        digitalWrite (FIRST_PIN + i, (value & (1 << (7 - i))) != 0 ? HIGH : LOW);
    }
    return;
}
 
Status
Not open for further replies.
Back
Top