How to interface a Hantick PS/2 touchpad with Arduino. Use it to crossfade a bicolor LED.
This is a simple project that can be built with other kind of input devices like potentiometer or joystick. But, my purpose was to get that touchpad working. I had to use a logic analyzer to determine its pinout. Luckily, since it uses PS/2 protocol, it sends some bytes without connection to a host device. The PS/2 protocol is well documented and pretty easy. ATmega microcontrollers used by Arduino boards don't have hardware support for this protocol, therefore it must be implemented in software. Some searching revealed a lot of libraries for PS/2 devices, but not all worked for me. This may be because the touchpad I used is pretty old and may not support all protocol features.
The touchpad I used is Hantick HTX5330M. I could not find a datasheet for it or for the IC it uses. It connects to motherboard by a 6 wire ribbon cable. Identifying power and ground lines is easy (most PCBs use GND as a plane and between this and VCC there are large capacitors). A closer look near the motherboard connector, shows two pull-up resistors of 7.5k.
Touchpad connector on motherboard |
Hantick HTX5330M touchpad |
Connect the touchpad and LED to Arduino |
The Arduino library that worked best for me is written by Jacek Kunicki and can be donwloaded from GitHub. It works in remote mode (it polls mouse/touchpad for new data every 20ms). Using this library, the code becomes very simple. Here is the Arduino sketch.
#include "PS2Mouse.h" #define DATA_PIN 5 #define CLOCK_PIN 6 PS2Mouse mouse(CLOCK_PIN, DATA_PIN); int red, green; void setup() { Serial.begin(9600); Serial.println("LED Crossfade with PS/2 Touchpad (or mouse)"); Serial.println("Using PS/2 librray by Jacek Kunicki (https://github.com/rucek)"); pinMode(9, OUTPUT); pinMode(10, OUTPUT); red = 127; green = 127; analogWrite(9, red); analogWrite(10, green); mouse.initialize(); } void loop() { MouseData data = mouse.readData(); red += data.position.x; green -= data.position.x; if (red > 255) red = 255; if (red < 0) red = 0; if (green > 255) green = 255; if (green < 0) green = 0; analogWrite(9, red); analogWrite(10, green); delay(20); }The LED is connected to PWM pins. The start-up duty cycle is 50% (127 is nearly half of 255). Only X axis is read and used to modify PWM duty cycle. The movement on X axis generates a relative value, which is positive for right swiping and negative for left swiping. This value is added to one of the LEDs and subtracted from the other. If it's positive, it will increase duty cycle of PWM signal that controls the LED to which is added and decrease the duty where it is subtracted. If it's negative, the opposite happens.
Hi! First off I wanna thank you so much for doing this! You got me a lot further than I could have gotten by myself :) My question to you though is if you can determine the pinout of the test points on the actual PCB? I lost the original motherboard connector so I need to tap into the test points directly, but there are more than the number of wires being used and I am not sure which is which. If you can't find them yourself, could you point me in the right direction to the information I will need to test them myself?
ReplyDeleteRotate my photo of the touchpad 180 degrees. The pins are then in the order you see in the breadboard diagram photo. Anyway, the thicker track on the touchpad PCB which comes from a side pin of the connector and goes to some capacitors is supply pin.
Delete/*please help me I downloaded the test code as such I get no station:*/
ReplyDelete#include
#include
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define SN761672A_ADDR (0xC2 >> 1)
// tuner registers
byte DB1, DB2, CB, BB;
uint32_t freq_kHz;
void setup()
{
Wire.begin();
lcd.backlight();
lcd.begin(16, 2);
//Tuner_init();
SN761672A_setTVFrequency(985000);
lcd.setCursor(0,0);
lcd.print("Station:");
}
void loop()
{
lcd.setCursor(8,0);
lcd.print(freq_kHz);
void SN761672A_setTVFrequency(uint32_t freq_kHz);
}
void SN761672A_setTVFrequency(uint32_t freq_kHz)
{
// band bits
if (freq_kHz < 168000) BB = 0x00; // band A, VHF-Lo
else if (freq_kHz < 448000) BB = 0x01; // band B, VHF-Hi
else BB = 0x08; // band C, UHF
// control
CB = 0xCA;//11001010
freq_kHz = freq_kHz / 31.25 + 1245;
DB1 = (freq_kHz >> 8) & 0x1F;
DB2 = freq_kHz & 0xFF;
Wire.beginTransmission(SN761672A_ADDR);
Wire.write(DB1);
Wire.write(DB2);
Wire.write(CB);
Wire.write(BB);
Wire.endTransmission();
}