# Help understanding shiftOut; Sending two seperate single digit ints (four bits each) in succession

Hello;

It seems I am unable to combine two separate ints in shiftOut. I am trying to control 3 nixie tubes, and I have the first one working no problem.

Here is the code:

``````/* This example code shows how to display temperature
*  from a standard 1 or 2 wire automotive coolant temperature
*  sensor. These types of sensors are a simple thermistor in
*  an industrial casing. Thermistor's change resistance based
*  on temperature. A voltage divider circuit must be used to
*  read the voltage to a microcontroller. Contact tylerovens@me.com
*  if you have any questions.
*/

#define coolantsensorDivider 3100   //defines the resistor value that is in series in the voltage divider
#define coolantsensorPin A0         //defines the analog pin of the input voltage from the voltage divider
#define NUMSAMPLES 5                //defines the number of samples to be taken for a smooth average

const float steinconstA = 0.00029747804005040700000;        //steinhart equation constant A, determined from wikipedia equations
const float steinconstB = 0.00030930965621690700000;       //steinhart equation constant B, determined from wikipedia equations
const float steinconstC = 0.00000019325617600466000;    //steinhart equation constant C, determined from wikipedia equations

int latchPin = 5;
int clockPin = 6;
int dataPin = 7;

int nixieOne;                                         //three variables to store nixie tube values obtained from temp sensor
int nixieTwo;
int nixieThree;

int samples[NUMSAMPLES];                              //variable to store number of samples to be taken

void setup() {
Serial.begin(9600);                                 //start serial monitor

pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);

}

void loop() {
uint8_t i;                                          //integer for loop
float average;                                      //decimal for average

for (i=0; i<NUMSAMPLES; i++) {
samples[i] = analogRead(coolantsensorPin);        //takes samples at number defined with a short delay between samples
delay(10);
}

average = 0;
for (i=0; i< NUMSAMPLES; i++) {
average += samples[i];                            //adds all number of samples together
}

average /= NUMSAMPLES;                              //divides by number of samples to output the average

average = (coolantsensorDivider*average)/(1023-average);        //conversion equation to read resistance from voltage divider

float steinhart;                              //steinhart equation to estimate temperature value at any resistance from curve of thermistor sensor
steinhart = log(average);                     //lnR
steinhart = pow(steinhart,3);                 //(lnR)^3
steinhart *= steinconstC;                     //C*((lnR)^3)
steinhart += (steinconstB*(log(average)));    //B*(lnR) + C*((lnR)^3)
steinhart += steinconstA;                     //Complete equation, 1/T=A+BlnR+C(lnR)^3
steinhart = 1.0/steinhart;                    //Inverse to isolate for T
steinhart -= 273.15;                          //Conversion from kelvin to celcius

float steinhartround = round(steinhart);      //roundz temp value to convert into int

int finaltemp;                                //declares "finaltemp" to be sp[lit
finaltemp = (steinhartround);

Serial.print("Temperature = ");
Serial.print(steinhartround);                      //prints final temp in celcius
Serial.println(" *F");

nixieOne = (finaltemp / 100) % 10;
nixieTwo = (finaltemp / 10) % 10;
nixieThree = finaltemp % 10;

Serial.print("nixieOne  ");
Serial.print(nixieOne);
Serial.print("      ");

Serial.print("nixieTwo  ");
Serial.print(nixieTwo);
Serial.print("      ");

Serial.print("nixieThree  ");
Serial.print(nixieThree);
Serial.print("      ");

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, nixieThree);
//shiftOut(dataPin, clockPin, MSBFIRST, nixieTwo);
digitalWrite(latchPin, HIGH);

}``````

I need to get int nixieOne, nixieTwo, and nixieThree shifted out but it seems like everytime its called, it clears the register;

Or if i try to use this:

shiftOut(dataPin, clockPin, MSBFIRST, nixieThree + nixieTwo);
it adds both int values and screws up the output.

Is there a way to combine the two without adding them, and shift them out? I poured over the 595 tutorial with no success.(googled a lot too)

Am I missing something?

Thanks in advance for the help

-Martine

Please post a schematic diagram. We need to see how the shift register outputs are connected to the Nixie display inputs. You need to explain how the digits are individually addressed.

A photo of a hand drawn diagram is fine, as long as all connections are clearly labeled.

Hint: this cannot possibly work as written:
`shiftOut(dataPin, clockPin, MSBFIRST, nixieThree + nixieTwo);`

As a learning experiment, write a program that simply displays the digits 1, 2 and 3 on tubes 1, 2 and 3.

The learning experiment you described is exactly what I'm trying to accomplish;

I discovered that bit of code;

shiftOut(dataPin, clockPin, MSBFIRST, nixieThree + nixieTwo);

Didn't work when it added both ints.

I'm almost certain the circuit is fine, all the leds light up when I plug it in, I have no problem getting large decimal numbers shifted out and lighting the led.

In this image you can see the green led lit up, just faintly. Corresponding to the binary table exactly; which is exactly what I need, as the outputs of the shift registers will be sent to the k155 nixie tube drivers.

I wanted to make sure the shift register portion of the code works, by assessing the correct led indicators, and comparing them with the temp and binary tables.

The problem is I just can't seem to get the last four red leds on the left lit up.

The ultimate goal is to have 3 nixie tubes, but I'm chipping it away a piece at a time, and this part I've been stuck on for days. With no avail.

I hope that clarifies

-Martine

You need to post a complete schematic, of the entire circuit, showing power, ground and all control signals.

There is nothing in what you posted showing how the individual display tubes are selected by the program.

Look up "display multiplexing". The same principles hold for 7-segment displays and Nixie tubes, and there are countless projects on line showing how to wire those displays.

Did you miss the part that said i am working on the shift register part first, and moving on to the high voltage tubes when im positive i'm sending the right bits to the k155

I just want to know if i can send two consecutive single digit ints out using shiftout, or if i need to use something different.

Im not going to multiplex this shit for 3 tubes brother, Its simple enough to get it done without. I just want help with the CODE hence, the post in the "Programming help" part of the forum

Welcome to my ignore list.

lets see... i'll try to explain it again for the ones in the back;
can I shiftOut two single digit ints;

Everytime I call shiftOut it seems to clear the entire registry of the shift register; Even if i do something like;

``````  digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, nixieTwo);
shiftOut(dataPin, clockPin, MSBFIRST, nixieThree);
digitalWrite(latchPin, HIGH);``````

It will wont send them in succession to the shiftregister,

``shiftOut(dataPin, clockPin, MSBFIRST, nixieThree);``

writes over

``shiftOut(dataPin, clockPin, MSBFIRST, nixieTwo);``

okay thanks for the "Help"

when you replied

" Hint: this cannot possibly work as written:
`shiftOut(dataPin, clockPin, MSBFIRST, nixieThree + nixieTwo);`"

when i literally said that in my first post right here;
"shiftOut(dataPin, clockPin, MSBFIRST, nixieThree + nixieTwo);
it adds both int values and screws up the output."

Wow, thanks for clarifying what i already mentioned.

I hate these condescending holier than thou types, giving me a "Hint"
you serious? LOL

Welcome to MY ignore list

I don't know for sure (I've never done this), but perhaps the problem is that you are sending int values to shiftOut(), when it says in the reference that it requires byte values.

I wonder if it is sending the high byte of the int (which would be all zeroes). Have you tried making nixieOne (etc) bytes rather than ints?

I think your right but shiftOut will convert an int into a byte value;

This part of the code takes the value of a thermistor; (the number which i am trying to display on the nixie tubes)

``````  float steinhart;                              //steinhart equation to estimate temperature value at any resistance from curve of thermistor sensor
steinhart = log(average);                     //lnR
steinhart = pow(steinhart,3);                 //(lnR)^3
steinhart *= steinconstC;                     //C*((lnR)^3)
steinhart += (steinconstB*(log(average)));    //B*(lnR) + C*((lnR)^3)
steinhart += steinconstA;                     //Complete equation, 1/T=A+BlnR+C(lnR)^3
steinhart = 1.0/steinhart;                    //Inverse to isolate for T
steinhart -= 273.15;                          //Conversion from kelvin to celcius

float steinhartround = round(steinhart);      //roundz temp value to convert into int

int finaltemp;                                //declares "finaltemp" to be sp[lit
finaltemp = (steinhartround);

Serial.print("Temperature = ");
Serial.print(steinhartround);                      //prints final temp in celcius
Serial.println(" *F");

nixieOne = (finaltemp / 100) % 10;
nixieTwo = (finaltemp / 10) % 10;
nixieThree = finaltemp % 10;``````

The only reason i used INTs was so I could split the three digit temperature reading into 3 seperate numbers;

My thinking was that everytime I use shiftOut i can plug "nixieOne, nixieTwo, etc" at the end of the argument;

or use multiple shiftOut statements.
But that didnt' seem to work either.

But you have just given me an idea!

I will turn both INTS into bytes;

and then concatenate both values, and THEN send it to the shift register

Let me try this. Thank you!

the nixie driver chip k155 (74141) accepts binary values which is perfect;
this is partly why I chose to go this route, due to simplicity;

shiftOut() always shifts 8 bits. You can't shift out 4 and you can't shift out 12. Your choices are 8 or 16.

Try this to see which set of 4 bits goes where:

``````  digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 0x12);
shiftOut(dataPin, clockPin, MSBFIRST, 0x34);
digitalWrite(latchPin, HIGH);
``````

I'm guessing you will get 2,3,4 (the 1 having been shifted off the top). If you get a different pattern, that will tell us which bits are landing where.

Okay, Thank you john, that makes sense.

I will make an example;
I have two values to shiftout; "nixieOne, and nixieTwo" (both single digit numbers).
So when i use;

`````` shiftOut(dataPin1, clockPin1, MSBFIRST, nixieOne);
shiftOut(dataPin1, clockPin1, MSBFIRST, nixieTwo);``````

"nixieOne" will be pushed down the register, and not even seen because "nixieTwo" will have been shifted into it's place.

My assumption was since 0-9 are 4 bit numbers, shiftOut will only send the necessary 4 bits; it doesn't say anything in the arduino ref about this...

So nixieTwo isnt writing over nixeOne, it's being shifted down the line; and since nixieTwo has nowhere to go it falls off the edge into the void
(Or is it actually being "Written over"??? " Is this how things are erased, and rewritten in a computer??)

SO... Last night with all this in mind I realised instead of trying to use just two shift registers, I will use three. and guess what; It finally worked! Hallelujah.

I wanted to get away with using two; 3 single digit numbers, converted into binary, 12 on/off states total.

So if you had LEDs on the outputs of a shift register, "175" would look like this;

``````1=high 0=low
The four leds on the lefthand side, never change;

0000|000101110101``````

And with that, I could take each binary value output from the 595, and wire it to the bcd to decimal convertor mentioned above.

But as we know now, that doesn't work. So instead I daisy chained 3 shift registers.
so that "175" looks like this(with an led on the output of each register)

``````1=high 0=low
00000001, 00000111, 00000101``````

I am left with a bunch up unused pins, and outputs I can't use, but that's okay.

At least it works now;
I can wire up the bcd to decimal.

Is there some fancy way to take those three integer values, "175"
and turn it into a string, or array like this; 000101110101 so that I CAN only use two shift registers? OR is this basically impossible?

175, which in this case would be our input from a thermistor is always changing its value, so I don't know if that would complicate things..

There would have to be some way to take each separate digit, "1" "7" and "5"
and take the binary value of each digit in the code;
Which I tried using byte, but that only left me with one digit, 0 or 1.
I'm also not sure how the arduino IDE handles binary numbers in the code, if they are also 8 bits bytes.

So basically, could you read a single digit byte value like, "7"
00000111

split that sucker in two,
0111

and add him in sequence with his other pals?
000101110101

Hope this makes sense, I am learning all the time; This stuff ain't easy but I'm on the right track.

Yes. Instead of sending three bytes:
00000001, 00000111, 00000101 (0x01, 0x07, 0x05)

you would send two:
00000001, 01110101 (0x01, 0x75)

To do that you would send nixieOne as usual, followed by:
(nixieTwo << 4) | nixieThree;
The 'shift left' operation (<<) moves the bottom four bits into the upper four bits, leaving space to put in another digit. After the shift, the bottom four bits are zeroes. You could use '+' in place of '|' (bitwise OR) since 0+x is the same as 0|x.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.