Hi guys, I am using an Arduino nano in conjunction with a UAA2022 16bit shift register to control a 16 segment display. The seriel data is sent via shiftOut.
The problem I'm having is the first bit is lost completely and the last bit is counted twice.
I have tried setting clock and latch pins to HI/LO in different combinations, but the only way I can get the shift register to work properly is to use a digitalWrite between shiftOut and latch to manually send an extra bit.
Has anyone experienced anything like this before? Any ideas?
Here is the complete sketch (problem is present)
//v1.5.1
//Input from photoresistor
const byte Brightness = A0;
//Input from X and Y poti's for gear position
const byte x_axis = A4;
const byte y_axis = A5;
//Outputs for UAA2022 display driver
const byte Data = 3;
const byte VDR = 4;
const byte CLK = 5;
const byte CO = 6;
//assign a number to R and N for neutral and reverse
const byte N = 0;
const byte R = 7;
const unsigned int Up = 3; // voltage Y Axis between 3rd and neutral gearstick position
const unsigned int Down = 2; // Vlotage Y Axis between 4th and neutral gearstick position
const unsigned int Left = 2; // voltage X Axis between 1st and 3rd gearstick position
const unsigned int Right = 3; // Voltage x Axis between 3rd and 5th gearstick position
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000; //the value is a number of milliseconds
int brightnessValue;
int brightnessOutput;
void setup()
{
startMillis = millis(); //initial start time
pinMode(Brightness, INPUT);
pinMode(x_axis, INPUT);
pinMode(y_axis, INPUT);
pinMode(Data, OUTPUT);
digitalWrite(VDR, HIGH);
pinMode(VDR, OUTPUT);
digitalWrite(CLK, HIGH);
pinMode(CLK, OUTPUT);
pinMode(CO, OUTPUT);
}
void updateGearIndicator(uint8_t first, uint8_t second)
{
digitalWrite(VDR, LOW); //ground vdr_tlach and hold low for as long as you are transmitting
//shiftout only supports one byte, so the 16 bits needed for display driver are split into 2 bytes
//The second byte is sent first.
shiftOut(Data, CLK, MSBFIRST, first);
shiftOut(Data, CLK, MSBFIRST, second);
//return the latch pin high to signal chi0 that it no longer needs Data to listen for information
digitalWrite(VDR, HIGH); //pull the VDR clock to save the data
}
void loop()
{
//Brightness control code
// runs every 1 seconds
currentMillis = millis();
if (currentMillis - startMillis >= period) {
//Create brightness value from photoresistor input
brightnessValue = analogRead(Brightness);
//Map Values between 0 to 255 for an output value
brightnessOutput = map(brightnessValue, 1, 1023, 1, 255);
startMillis = currentMillis;
}
//Send brightness value as constant PWM to display driver.
analogWrite(CO, brightnessOutput);
//Gear indicator
// read the input from x axis poti.
int x_input = analogRead(x_axis);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float x_position = x_input * (5.0 / 1023.0);
// repeat for y axis
int y_input = analogRead(y_axis);
float y_position = y_input * (5.0 / 1023.0);
if (y_position < Up && y_position > Down)
//Neutral
{
updateGearIndicator(B01100001, B01100001);
}
if (x_position < Left && y_position > Up)
//First
{
updateGearIndicator(B01000000, B00000101);
}
if (x_position < Left && y_position < Down)
//Second
{
updateGearIndicator(B10010011, B10010011);
}
if (x_position > Left && x_position < Right && y_position > Up)
//Third
{
updateGearIndicator(B01010010, B10010011);
}
if (x_position > Left && x_position < Right && y_position < Down)
//Fourth
{
updateGearIndicator(B01000000, B11000001);
}
if (x_position > Right && y_position > Up)
//Fifth
{
updateGearIndicator(B01010010, B11010010);
}
if (x_position > Right && y_position < Down)
//Reverse
{
updateGearIndicator(B00100001, B11010011);
}
}
Here is a snippet of how i can make it work by sending an extra bit manually
if (x_position < Left && y_position > Up){
digitalWrite(vdr_latch,LOW);
shiftOut(data_output,clk,MSBFIRST,B01000000);
shiftOut(data_output,clk,MSBFIRST,B00000101);
digitalWrite(data_output, LOW);
digitalWrite(vdr_latch,HIGH);
}
if (x_position < Left && y_position < Down){
digitalWrite(vdr_latch,LOW);
shiftOut(data_output,clk,MSBFIRST,B00010011);
shiftOut(data_output,clk,MSBFIRST,B10010011);
digitalWrite(data_output, HIGH);
digitalWrite(vdr_latch,HIGH);
}