adelle
November 4, 2022, 5:35am
1
These #define (s) work fine:
#define CLK4 19 // pin 28
#define DAT4 18 // pin 27
void set_port()
{
pinMode(CLK4, OUTPUT);
digitalWrite(CLK4, 1);
pinMode(DAT4, OUTPUT);
digitalWrite(DAT4, 1);
}
These do not and are dead. Why?
#define CLK1 9 // pin 15
#define DAT1 10 // pin 16
void set_port()
{
pinMode(CLK1, OUTPUT);
digitalWrite(CLK1, 1);
pinMode(DAT1, OUTPUT);
digitalWrite(DAT1, 1);
}
Is there something more I need to do to use PORTB as digital output on the ATMEGA328 via the Uno board?
NOTE: This is not a bad chip. I already swapped it out with no change.
westfw
November 4, 2022, 6:02am
2
Nope. That should work fine.
b707
November 4, 2022, 7:58am
3
test it with bare numbers:
adelle
November 4, 2022, 5:12pm
5
Full listing. Note there are no #include files or third party libraries. It's all here! This is a four port PS2 keyboard emulator to send keyboard commands to some industrial hardware that uses a plain PS2 keyboard for remote control.
You send two characters via RS232, first is ASCII 1 thru 4 to select the PS2 port, the second is the keyboard character you want to send, Followed by a CR (0xD). Note the conversion to PS2 scan codes is handled by this code.
Snippets of this code are derived and modified from PS2keypolled written by forum member"westfw".
* ps2emu_poll.c
*/
/* PS2 connector pinout
* 1- DATA
* 2- nc
* 3- GND
* 4- +5v
* 5- CLK
* 6- nc
*/
#define CLK_PULSE 10
#define MAX_CHAR 10
/* PS2 port Arduino // ATMEGA328 pin assignments */
#define CLK1 9 // pin 15
#define DAT1 10 // pin 16
#define CLK2 14 // pin 23
#define DAT2 15 // pin 24
#define CLK3 16 // pin 25
#define DAT3 17 // pin 26
#define CLK4 18 // pin 27
#define DAT4 19 // pin 28
unsigned char ps2k_clk, ps2k_dat;
char inputString[MAX_CHAR];
unsigned char_cnt= 0;
bool stringComplete = false;
unsigned char ScanCode[256];
unsigned char kybd_port[4][2];
void setup() {
unsigned char n;
/* load port pin array */
load_ScanCodes();
kybd_port[0][0]= CLK1;
kybd_port[0][1]= DAT1;
kybd_port[1][0]= CLK2;
kybd_port[1][1]= DAT2;
kybd_port[2][0]= CLK3;
kybd_port[2][1]= DAT3;
kybd_port[3][0]= CLK4;
kybd_port[3][1]= DAT4;
for (n= 0; n<= 3; n++)
ps2k_init (kybd_port[n][0],kybd_port[n][1]);
Serial.begin(9600); /* initialize serial */
}
void ps2k_init (unsigned char clock, unsigned char data)
{
ps2k_clk = clock;
ps2k_dat = data;
pinMode(ps2k_clk, OUTPUT);
digitalWrite(ps2k_clk, 1); /* Claim the clock */
pinMode(ps2k_dat, OUTPUT);
digitalWrite(ps2k_dat, 0); /* Enable pullups */
}
void loop()
{
unsigned char n;
/*
ps2k_clk= kybd_port[3][0];
ps2k_dat= kybd_port[3][1];
ps2k_sendbyte(ScanCode['A']);
Serial.println("Running");
*/
if (stringComplete) {
Serial.println(inputString);
n= (inputString[0] - 0x31);
if (((n >= 1)&&(n <= 4))&&(ScanCode[inputString[1]] > 0)) {
ps2k_clk= kybd_port[n][0];
ps2k_dat= kybd_port[n][1];
ps2k_sendbyte(ScanCode[inputString[1]]);
}
inputString[0]= 0; // clear the string:
stringComplete = false;
}
}
void ps2k_sendbyte(unsigned char code)
{
unsigned char parity = 0; /* Get first byte */
unsigned char i;
/* send start bit */
digitalWrite(ps2k_dat, 0);
delayMicroseconds(CLK_PULSE);
digitalWrite(ps2k_clk, 0);
delayMicroseconds(CLK_PULSE);
digitalWrite(ps2k_clk, 1);
/* Send 8 data bits, LSB first */
for (i = 0; i < 8; i++) { /* Send 8 data bits, LSB first */
if (code & 0x1) {
digitalWrite(ps2k_dat, 1);
parity++; /* Count one bits to calculate parity */
}
else
digitalWrite(ps2k_dat, 0);
delayMicroseconds(CLK_PULSE);
digitalWrite(ps2k_clk, 0);
delayMicroseconds(CLK_PULSE);
digitalWrite(ps2k_clk, 1);
code >>= 1; /* Shift to get next bit ready. */
}
/* Send proper parity bit */
if ((parity & 0x1))
digitalWrite(ps2k_dat, 0);
else
digitalWrite(ps2k_dat, 1);
delayMicroseconds(CLK_PULSE);
digitalWrite(ps2k_clk, 0);
delayMicroseconds(CLK_PULSE);
digitalWrite(ps2k_clk, 1);
/* Send stop bit */
digitalWrite(ps2k_dat, 1);
delayMicroseconds(CLK_PULSE);
digitalWrite(ps2k_clk, 0);
delayMicroseconds(CLK_PULSE);
digitalWrite(ps2k_clk, 1);
digitalWrite(ps2k_dat, 0);
}
void serialEvent()
{
char inChar;
while (Serial.available()) {
if (char_cnt == (MAX_CHAR - 1))
char_cnt= 0;
inChar= (char)Serial.read();
inputString[char_cnt++]= inChar;
if (inChar == 0xD) {
char_cnt= 0;
stringComplete = true;
}
}
}
void load_ScanCodes()
{
/* Listed are PRESS scan codes. For RELEASE codes, first send 0xF0, then listed scancode */
ScanCode['1'] = 0x16;
ScanCode['2'] = 0x1E;
ScanCode['3'] = 0x26;
ScanCode['4'] = 0x25;
ScanCode['5'] = 0x2E;
ScanCode['6'] = 0x36;
ScanCode['7'] = 0x3D;
ScanCode['8'] = 0x3E;
ScanCode['9'] = 0x46;
ScanCode['0'] = 0x45;
ScanCode['A'] = 0x1C;
ScanCode['B'] = 0x32;
ScanCode['C'] = 0x21;
ScanCode['D'] = 0x23;
ScanCode['E'] = 0x24;
ScanCode['F'] = 0x2B;
ScanCode['G'] = 0x34;
ScanCode['H'] = 0x33;
ScanCode['I'] = 0x43;
ScanCode['J'] = 0x3B;
ScanCode['K'] = 0x42;
ScanCode['L'] = 0x4B;
ScanCode['M'] = 0x3A;
ScanCode['N'] = 0x31;
ScanCode['O'] = 0x44;
ScanCode['P'] = 0x4D;
ScanCode['Q'] = 0x15;
ScanCode['R'] = 0x2D;
ScanCode['S'] = 0x1B;
ScanCode['T'] = 0x2C;
ScanCode['U'] = 0x3C;
ScanCode['V'] = 0x2A;
ScanCode['W'] = 0x1D;
ScanCode['X'] = 0x22;
ScanCode['Y'] = 0x35;
ScanCode['Z'] = 0x1A;
ScanCode[';'] = 0x4C;
ScanCode[','] = 0x41;
ScanCode['.'] = 0x49;
ScanCode['/'] = 0x4A;
ScanCode['*'] = 0x7C;
ScanCode['-'] = 0x7B;
ScanCode['+'] = 0x79;
ScanCode['.'] = 0x71;
ScanCode['='] = 0x55;
ScanCode[0x91] = 0x05; // F1
ScanCode[0x92] = 0x06; // F2
ScanCode[0x93] = 0x04; // F3
ScanCode[0x94] = 0x0C; // F4
ScanCode[0x95] = 0x03; // F5
ScanCode[0x96] = 0x0B; // F6
ScanCode[0x97] = 0x83; // F7
ScanCode[0x98] = 0x0A; // F8
ScanCode[0x99] = 0x01; // F9
ScanCode[0x9A] = 0x09; // F10
ScanCode[0x9B] = 0x78; // F11
ScanCode[0x9C] = 0x07; // F12
ScanCode[0x20] = 0x29; // space
ScanCode[0x08] = 0x66; // back
ScanCode[0x1B] = 0x76; // esc
ScanCode[0x80] = 0x12; // shift left
ScanCode[0x81] = 0x59; // shift right
ScanCode[0x82] = 0x58; // caps lock
}
If you print these values, are they plausible?
Is this
(n >= 1)&&(n <= 4)
correct? Array indices run from 0 to size - 1.
At a glance through the small window. HTH.
a7
adelle
November 4, 2022, 5:33pm
7
I just noticed the same thing! Yes that appears to be the bug. I force the received port number to start at zero as not to waste memory in a dead array address(s). Note I come from the 8051 days when that was important. I guess today not so much. The ATMEGA328 has what, 32K of code memory?
Heavies and old-timers will look to save any byte they can, no matter. And any microseconds that can be shaved must. Be shaved.
But the Arduino boards have, from a certain point of view, vast resources. Add that amazing optimiser in the compiler and you can relax about many things.
Best: programs that use a fraction of the resources, like 1/3. Never worry about running out of anything.
If you aren't fluent in C/C++ it is never too early to start using zero the way it is… number things from zero is the start and yes, you'll get yourself confused once in a while.
a7
b707
November 4, 2022, 11:28pm
9
The problem is not at all a waste of memory for one element. When you work with an array of 4 elements with such a condition,
(n >= 1)&&(n <= 4)
you have an array overflow with memory corruption, after which the program may work incorrectly or even hang
Not always It can be really important that the body of an if takes the same time as the body of the associated else .
We used to fill an empty else body with NOPs to achieve that.
system
Closed
May 6, 2023, 1:10pm
11
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.