fallback VID PID + hex json + RE info, keypad WIP

This commit is contained in:
2026-03-18 00:57:38 -03:00
parent 48632ae058
commit 1e44efda5e
5 changed files with 112 additions and 49 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,12 +1,15 @@
package main package main
import ( import (
_ "embed"
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
"image/color" "image/color"
"net/http" "net/http"
"os" "os"
"strconv"
"strings"
"time" "time"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
@@ -17,10 +20,35 @@ import (
"github.com/google/gousb" "github.com/google/gousb"
) )
//go:embed icon.ico
var iconData []byte
type HexUint16 uint16
func (h HexUint16) MarshalJSON() ([]byte, error) {
return json.Marshal(fmt.Sprintf("0x%04X", h))
}
func (h *HexUint16) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
s = strings.TrimPrefix(s, "0x")
val, err := strconv.ParseUint(s, 16, 16)
if err != nil {
return err
}
*h = HexUint16(val)
return nil
}
type Config struct { type Config struct {
TargetURL string `json:"target_url"` TargetURL string `json:"target_url"`
VendorID uint16 `json:"vendor_id"` VendorID HexUint16 `json:"vendor_id"`
ProductID uint16 `json:"product_id"` ProductID HexUint16 `json:"product_id"`
FallbackVID HexUint16 `json:"fallback_vendor_id"`
FallbackPID HexUint16 `json:"fallback_product_id"`
} }
var hidMap = map[byte]string{ var hidMap = map[byte]string{
@@ -52,12 +80,13 @@ func loadConfig() Config {
TargetURL: "https://scanner.sekidesu.xyz/scan", TargetURL: "https://scanner.sekidesu.xyz/scan",
VendorID: 0xFFFF, VendorID: 0xFFFF,
ProductID: 0x0035, ProductID: 0x0035,
FallbackVID: 0x04B3,
FallbackPID: 0x3107,
} }
file, err := os.ReadFile("config.json") file, err := os.ReadFile("config.json")
if err == nil { if err == nil {
json.Unmarshal(file, &conf) json.Unmarshal(file, &conf)
} else { } else {
// Create default config if missing
data, _ := json.MarshalIndent(conf, "", " ") data, _ := json.MarshalIndent(conf, "", " ")
os.WriteFile("config.json", data, 0644) os.WriteFile("config.json", data, 0644)
} }
@@ -82,6 +111,8 @@ func main() {
a := app.New() a := app.New()
w := a.NewWindow("POS Hardware Bridge (Go)") w := a.NewWindow("POS Hardware Bridge (Go)")
w.SetIcon(fyne.NewStaticResource("icon.ico", iconData))
bridge.window = w bridge.window = w
bridge.urlEntry = widget.NewEntry() bridge.urlEntry = widget.NewEntry()
bridge.urlEntry.SetText(conf.TargetURL) bridge.urlEntry.SetText(conf.TargetURL)
@@ -179,13 +210,17 @@ func (b *BridgeApp) usbListenLoop() {
for { for {
dev, err := ctx.OpenDeviceWithVIDPID(gousb.ID(b.config.VendorID), gousb.ID(b.config.ProductID)) dev, err := ctx.OpenDeviceWithVIDPID(gousb.ID(b.config.VendorID), gousb.ID(b.config.ProductID))
if (err != nil || dev == nil) && (b.config.FallbackVID != 0) {
dev, err = ctx.OpenDeviceWithVIDPID(gousb.ID(b.config.FallbackVID), gousb.ID(b.config.FallbackPID))
}
if err != nil || dev == nil { if err != nil || dev == nil {
b.updateStatus("Scanner unplugged. Waiting...", color.NRGBA{200, 0, 0, 255}) b.updateStatus("Scanner unplugged. Waiting...", color.NRGBA{200, 0, 0, 255})
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
continue continue
} }
b.updateStatus("Scanner Locked & Ready", color.NRGBA{0, 180, 0, 255}) b.updateStatus(fmt.Sprintf("Scanner Ready (0x%04X)", dev.Desc.Vendor), color.NRGBA{0, 180, 0, 255})
intf, done, err := dev.DefaultInterface() intf, done, err := dev.DefaultInterface()
if err != nil { if err != nil {

Binary file not shown.

Binary file not shown.

View File

@@ -1,48 +1,76 @@
#include <Arduino.h> #include <Arduino.h>
const int BUZZER_PIN = 6; const int BUZZER_PIN = 6;
const int allPins[] = {0, 1, 2, 3, 4, 5, 7}; const int pins[] = {0, 1, 2, 3, 4, 5, 7};
const int numPins = 7; const int numPins = 7;
unsigned long lastDebounceTime = 0; struct KeyMap {
const int debounceDelay = 250; int strobe;
int target;
char key;
};
// Your discovered mapping
KeyMap keypad[] = {{7, 1, '1'}, {7, 2, '2'}, {3, 7, '3'}, {5, 0, 'C'},
{7, 0, 'T'}, {4, 1, 'm'}, {1, 2, 'Y'}, {5, 3, '6'},
{1, 0, '+'}, {2, 0, 'Z'}, {1, 5, '7'}, {5, 2, 'U'},
{2, 5, '8'}, {3, 5, '9'}, {2, 4, 'M'}, {3, 1, '4'},
{0, 2, '5'}, {3, 4, 'P'}, {4, 0, '$'}, {0, 4, 'L'}};
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
for (int i = 0; i < numPins; i++) { for (int p : pins) {
pinMode(allPins[i], INPUT_PULLUP); pinMode(p, INPUT_PULLUP);
} }
// Keep buzzer pin high-impedance so it doesn't sink the matrix
pinMode(BUZZER_PIN, INPUT_PULLUP);
} }
void loop() { void playBeep() {
// Only scan if we aren't in the middle of a "hit" lockout analogWrite(BUZZER_PIN, 10);
if (millis() - lastDebounceTime < debounceDelay) return;
delay(50); // Beep duration
analogWrite(BUZZER_PIN, 0); // Turn it off
pinMode(BUZZER_PIN, INPUT_PULLUP); // Reset to input for the matrix
}
char getKeyPressed() {
for (int s = 0; s < numPins; s++) { for (int s = 0; s < numPins; s++) {
int strobe = allPins[s]; int strobe = pins[s];
pinMode(strobe, OUTPUT); pinMode(strobe, OUTPUT);
digitalWrite(strobe, LOW); digitalWrite(strobe, LOW);
delayMicroseconds(100); // Slightly longer for stability delayMicroseconds(50);
for (int i = 0; i < numPins; i++) { for (int i = 0; i < numPins; i++) {
int target = allPins[i]; int target = pins[i];
if (target == strobe) continue; if (target == strobe)
continue;
if (digitalRead(target) == LOW) { if (digitalRead(target) == LOW) {
// WE FOUND ONE! for (int k = 0; k < 20; k++) {
Serial.print("SINK:"); if (keypad[k].strobe == strobe && keypad[k].target == target) {
Serial.print(strobe);
Serial.print(" READ:");
Serial.println(target);
//tone(BUZZER_PIN, 2000, 50); // Visual and Audio feedback
lastDebounceTime = millis(); Serial.print("Pressed: ");
Serial.println(keypad[k].key);
playBeep();
while (digitalRead(target) == LOW)
; // Wait for release
pinMode(strobe, INPUT_PULLUP); pinMode(strobe, INPUT_PULLUP);
return; // Jump out of the whole loop to reset the lockout return keypad[k].key;
}
}
} }
} }
pinMode(strobe, INPUT_PULLUP); pinMode(strobe, INPUT_PULLUP);
} }
return '\0';
}
void loop() {
getKeyPressed();
delay(10);
} }