Hi there, i'm not totally new to arduino but I haven't done a lot of my own programming, mostly dissecting existing code and trying to make it work.
I'm using the code from this:
http://playground.arduino.cc/Code/ShiftRegSN74HC165N
and I'm trying to get the individual 74hc165's "high" states to trigger a conditional statement
(very roughly) "if pin 3 is high then print this hex keycode"
I have a hunch I'm going to need to modify the void display_pin_values() section, correct?
OR
How would you go about interpreting the 74hc165 to mimmick the arduino's built in digital i/o pins (code wise)?
shift_in_test.ino (3.67 KB)
Hi there, i'm not totally new to arduino but I haven't done a lot of my own programming, mostly dissecting existing code and trying to make it work.
I'm using the code from this:
http://playground.arduino.cc/Code/ShiftRegSN74HC165N
and I'm trying to get the individual 74hc165's "high" states to trigger a conditional statement
(very roughly) "if pin 3 is high then print this hex keycode"
I have a hunch I'm going to need to modify the void display_pin_values() section, correct?
OR
How would you go about interpreting the 74hc165 to mimmick the arduino's built in digital i/o pins (code wise)?
spirit
April 2, 2016, 10:18am
3
hi , and interesting.
i also have a project that uses the 74hc165 and never realy made the code better.
first of all nice to know you dont need 4 wires you can do it with 3!
Clock, Latch and Data.
and to give you a idea here ismy example.
#define dataPin 47
#define clkPin 51
#define latchPin 53
void setup() {
Serial.begin(9600);
pinMode(dataPin, INPUT);
pinMode(clkPin, OUTPUT);
pinMode(latchPin, OUTPUT);
}
void loop() {
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
Serial.println(shift_In(dataPin, clkPin, LSBFIRST), BIN);
}
uint8_t shift_In(uint8_t data_Pin, uint8_t clk_Pin, uint8_t bitOrder) {
uint8_t shiftvalue = 0;
for (uint8_t x = 0; x < 8; x++) {
digitalWrite(clk_Pin, LOW);
if (bitOrder == LSBFIRST)
shiftvalue |= digitalRead(data_Pin) << x;
else
shiftvalue |= digitalRead(data_Pin) << (7 - x);
digitalWrite(clk_Pin, HIGH);
}
return shiftvalue;
}
and now you can say when bitRead(val, 2) == 1 then print something on the serial port.
or as you did when val != oldval print all 8 bits.
and what you see is just the same shiftIn function from arduino. only i made a change to the clock high and low. with the arduino function you only get 7 bits it misses one. and with my function you get all 8 bits.
you must be using a mega or due (based on the pin numbers you used?)
I tried adjusting the pin numbers to suit the uno, but no go on compile.
So you never got it working?
spirit
April 2, 2016, 10:29am
5
yes i do use the DUE but it must be the same. as on a uno or mega.
i dont use special due or mega codes or something.
oke i changed to uno and changed the pin numbers but compile's fine at my side.
and offcourse the code is working otherwise i would not show it to you.
same but changed to
int dataPin = 11;
int clkPin = 12;
int latchPin = 9;
compiled fine but just getting 0's in the serial monitor.
Based on the tutorial I linked, I didn't see the "latch" pin...which pin number on the 165 is it?
spirit
April 2, 2016, 10:40am
7
Link
see link so we talk at the same level. page 3
i use :
pin 1 "PL" as LACTH
pin 2 "CP" as CLOCK (clk)
pin 9 "Q7" as DATA
and pin 8 and pin 15 must go to GND
and pin 16 to 5+
Ok, cool.
I'm getting several values for button presses in the serial monitor now:
10000 for one pin
then when i switch pins,
(then zero when no button is pushed)
How would I go about using those values in a conditional statement?
First thing to know is that Serial.println is very primitive. It will omit leading zeros. So a pattern line 1000 is actually 00001000.
To get your code to recognize individual buttons, it's very nice to give them sensible names first. Below an example for e.g. a video recorder .
#define BUTTON_PLAY 0x01
#define BUTTON_STOP 0x02
#define BUTTON_FASTFORW 0x04
#define BUTTON_REWIND 0x08
#define BUTTON_PAUSE 0x10
#define BUTTON_RECORD 0x20
#define BUTTON_SLOWMO 0x40
They must be multiples of 2 (1, 2, 4, 8, ...)
After reading your 165, you can now analyze your data
void loop() {
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
byte buttons = shift_In(dataPin, clkPin, LSBFIRST);
switch (buttons)
{
case BUTTON_PLAY:
Serial.println("Play");
break;
case BUTTON_STOP:
Serial.println("Stop");
break;
...
...
default:
Serial.println("Multiple buttons pressed or unsupported button");
}
}
The above can not cater for multiple buttons (OK, with some difficulty). The second option is to use 'binary and' in a if
void loop() {
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
byte buttons = shift_In(dataPin, clkPin, LSBFIRST);
if ((buttons & BUTTON_PLAY) == BUTTON_PLAY)
{
}
else if ((buttons & BUTTON_STOP) == BUTTON_STOP)
{
}
else if((buttons & BUTTON_FASTFORW) == BUTTON_FASTFORW && (buttons & BUTTON_REWIND) == BUTTON_REWIND)
{
Serial.println("Make up your mind");
}
else if ...
...
}
PaulRB
April 2, 2016, 2:30pm
10
Hello,
Its not a great bit of code and not easy for a beginner to understand. There are more commands available in the Arduino language these days, compared to when i suspect that code was written, which might make it easier to understand. These include shiftIn() and bitRead().
Can you explain in more detail what you want to do, and give us a schematic diagram. We can help you write some easier code.
Paul
spirit
April 2, 2016, 3:42pm
12
hi again.
here a new code and as you sad i like to have it the same as digitalRead();
now i added shiftRead(pinNumber);
and when you add a second 165 you can keep up counting 8,9,10,11 enz.....
#define NUMBER_OF_SHIFT_CHIPS 1
uint8_t shiftvalue[NUMBER_OF_SHIFT_CHIPS];
#define dataPin 47
#define clkPin 51
#define latchPin 53
#define button1 0
#define button2 1
void setup() {
Serial.begin(9600);
pinMode(dataPin, INPUT);
pinMode(clkPin, OUTPUT);
pinMode(latchPin, OUTPUT);
}
void loop() {
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
shift_In(dataPin, clkPin, LSBFIRST);
//Test to see all 8 bits.
/*for (uint8_t x = 0; x < 8; x++) {
Serial.print(shiftRead(x), BIN);
}
Serial.println();*/
//Test for #define button names
//Serial.println(shiftRead(button1));
// or
if(shiftRead(button1) == HIGH){
Serial.println("Button 1 = HIGH");
} else {
Serial.println("Button 1 = LOW");
}
}
void shift_In(uint8_t data_Pin, uint8_t clk_Pin, uint8_t bitOrder) {
for (uint8_t y = 0; y < NUMBER_OF_SHIFT_CHIPS; y++) {
shiftvalue[y] = 0;
}
for (uint8_t y = 0; y < NUMBER_OF_SHIFT_CHIPS; y++) {
for (uint8_t x = 0; x < 8; x++) {
digitalWrite(clk_Pin, LOW);
if (bitOrder == LSBFIRST)
shiftvalue[y] |= digitalRead(data_Pin) << x;
else
shiftvalue[y] |= digitalRead(data_Pin) << (7 - x);
digitalWrite(clk_Pin, HIGH);
}
}
}
uint8_t shiftRead(uint8_t pin) {
uint8_t pinmodulo = pin % 8;
uint8_t array = pin / 8;
return bitRead(shiftvalue[array], pinmodulo);
}
and just for other poeple im not a profesional i just do it for the fun and i know the shiftread could be coded better. or al least i think it can be better.
i did not test with 2x165 so maby it doesnt work!
Do not cross-post. Threads merged.
Ok, getting used to the forums here still. I wasn't sure where this question would fit best.
I'll try that code and see what happens, sterretje, spirit. thank you.
Paul, I'm using the code and schematic from: Arduino Playground - ShiftRegSN74HC165N
with just one register (unused pins grounded)
I'm basically just trying to read the 74hc165 then send keyboard scancodes based on that input (example: E0, F0, 4D) with some other code i found that emulates a REAL PS/2 keyboard over an actual PS/2 cable
sterretje- were you basing your code off of spirit's original code?
Yep, I think I did; although not knowingly as I thought it was your code
Great, got it going. Thank you both again.
Ooops forgot to ask- Spirit or sterretje, would the code work for more than 2 chips? or would i need to put "long" somewhere in there
spirit's second code (in reply #11 ) seems to cater for that. This basically allows for limitless expansion without having to 'think'.
Or you can modify the shift_In in spirit's first code to return an uint16_t, uint32_t or uint64_t; below shown for uint64_t (64 bits).
uint64_t shift_In(uint8_t data_Pin, uint8_t clk_Pin, uint8_t bitOrder) {
uint64_t shiftvalue = 0;
for (uint8_t x = 0; x < 64; x++) {
digitalWrite(clk_Pin, LOW);
if (bitOrder == LSBFIRST)
shiftvalue |= digitalRead(data_Pin) << x;
else
shiftvalue |= digitalRead(data_Pin) << (7 - x);
digitalWrite(clk_Pin, HIGH);
}
return shiftvalue;
}