Author Topic: Issue with hand-wired numpad  (Read 4991 times)

0 Members and 1 Guest are viewing this topic.

Offline 3K

  • Thread Starter
  • Posts: 279
  • Location: Germany
Issue with hand-wired numpad
« on: Fri, 14 August 2015, 08:06:42 »
So I just handwired (first time) an external numpad, put in a teensy, burned the firmware following matt3os guide and am now experiencing random inputs of 3 certain characters on my numpad. (fast enough to not allow any other input)
I checked the source code twice and couldn't find any visible shorts.. so what could the problem be? I don't know what to do anymore.  :-X
« Last Edit: Fri, 14 August 2015, 10:50:57 by HoffmanMyster »

                   Model M '88    | Model M SSK '87 | HHKB P2  | Zowie FK1

Offline CPTBadAss

  • Woke up like this
  • Posts: 14365
    • Tactile Zine
Re: Re: Simple Questions, Simple Answers (FAQ in the OP)
« Reply #1 on: Fri, 14 August 2015, 08:09:28 »
So I just handwired (first time) an external numpad, put in a teensy, burned the firmware following matt3os guide and am now experiencing random inputs of 3 certain characters on my numpad. (fast enough to not allow any other input)
I checked the source code twice and couldn't find any visible shorts.. so what could the problem be? I don't know what to do anymore.  :-X

Could also be bad solder joint of a switch, wire, or a leg on the teensy. Have you tried using a multimeter to check all your joints?

Also this isn't really a simple question. There's a lot of variables to check. I suggest making a new thread and posting your code to see if you missed something. And then the new thread could also bring more visibility as to other ideas you can check. Finally, you can look over the handwire thread to see if you can find any clues.

Offline HoffmanMyster

  • HOFF, smol MAN OF MYSTERY
  • * Senior Moderator
  • Posts: 11461
  • Location: WI
Re: Issue with hand-wired numpad
« Reply #2 on: Fri, 14 August 2015, 10:52:32 »
Bump for topic split. :thumb:

Offline 3K

  • Thread Starter
  • Posts: 279
  • Location: Germany
Re: Issue with hand-wired numpad
« Reply #3 on: Fri, 14 August 2015, 13:23:25 »
So I just handwired (first time) an external numpad, put in a teensy, burned the firmware following matt3os guide and am now experiencing random inputs of 3 certain characters on my numpad. (fast enough to not allow any other input)
I checked the source code twice and couldn't find any visible shorts.. so what could the problem be? I don't know what to do anymore.  :-X

Could also be bad solder joint of a switch, wire, or a leg on the teensy. Have you tried using a multimeter to check all your joints?

Also this isn't really a simple question. There's a lot of variables to check. I suggest making a new thread and posting your code to see if you missed something. And then the new thread could also bring more visibility as to other ideas you can check. Finally, you can look over the handwire thread to see if you can find any clues.

After looking up what exactly makes a solder point 'bad' and what a multimeter is, I decided that I probably should resolder teh whole thing.
I could now post a picture of the matrix... but I guess there are underaged user on this site too.

Also I noticed my solder iron is with 30W a little too strong.

Bump for topic split. :thumb:
Thanks for the thread!


                   Model M '88    | Model M SSK '87 | HHKB P2  | Zowie FK1

Offline 3K

  • Thread Starter
  • Posts: 279
  • Location: Germany
Re: Issue with hand-wired numpad
« Reply #4 on: Fri, 21 August 2015, 03:20:45 »
After resoldering most of the contacts with a better iron I'm still experiencing the same issues.

If there's someone who could check my source code I'd be very thankful. (just checked everything for the 5th time or something like that)

pin assignment


matrix.c
Code: [Select]
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * scan matrix
 */
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"


#ifndef DEBOUNCE
#   define DEBOUNCE 5
#endif
static uint8_t debouncing = DEBOUNCE;

/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];

static matrix_row_t read_cols(void);
static void init_cols(void);
static void unselect_rows(void);
static void select_row(uint8_t row);


inline
uint8_t matrix_rows(void)
{
    return MATRIX_ROWS;
}

inline
uint8_t matrix_cols(void)
{
    return MATRIX_COLS;
}

void matrix_init(void)
{
    // initialize row and col
    unselect_rows();
    init_cols();

    // initialize matrix state: all keys off
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
        matrix[i] = 0;
        matrix_debouncing[i] = 0;
    }
}

uint8_t matrix_scan(void)
{
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        select_row(i);
        _delay_us(30);  // without this wait read unstable value.
        matrix_row_t cols = read_cols();
        if (matrix_debouncing[i] != cols) {
            matrix_debouncing[i] = cols;
            if (debouncing) {
                debug("bounce!: "); debug_hex(debouncing); debug("\n");
            }
            debouncing = DEBOUNCE;
        }
        unselect_rows();
    }

    if (debouncing) {
        if (--debouncing) {
            _delay_ms(1);
        } else {
            for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
                matrix[i] = matrix_debouncing[i];
            }
        }
    }

    return 1;
}

bool matrix_is_modified(void)
{
    if (debouncing) return false;
    return true;
}

inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
    return (matrix[row] & ((matrix_row_t)1<<col));
}

inline
matrix_row_t matrix_get_row(uint8_t row)
{
    return matrix[row];
}

void matrix_print(void)
{
    print("\nr/c 0123456789ABCDEF\n");
    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
        phex(row); print(": ");
        pbin_reverse16(matrix_get_row(row));
        print("\n");
    }
}

uint8_t matrix_key_count(void)
{
    uint8_t count = 0;
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        count += bitpop16(matrix[i]);
    }
    return count;
}

/* Column pin configuration
 * col: 0   1   2   3
 * pin: F0  F1  F4  F5   (Rev.A)
 * pin:                  (Rev.B)
 */
static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
    DDRF  &= ~(1<<0 | 1<<1 | 1<<4 | 1<<5);
    PORTF |=  (1<<0 | 1<<1 | 1<<4 | 1<<5);
   
}

static matrix_row_t read_cols(void)
{
    return (PINF&(1<<0) ? 0 : (1<<0)) |
           (PINF&(1<<1) ? 0 : (1<<1)) |
           (PINF&(1<<4) ? 0 : (1<<2)) |
           (PINF&(1<<5) ? 0 : (1<<3))
;
}

/* Row pin configuration
 * row: 0   1   2   3   4
 * pin: F6  F7  B6  B5  B4
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    DDRF  &= ~0b00110011;
    PORTF &= ~0b00110011;
}

static void select_row(uint8_t row)
{
    // Output low(DDR:1, PORT:0) to select
    switch (row) {
        case 0:
            DDRF  |= (1<<6);
            PORTF &= ~(1<<6);
            break;
        case 1:
            DDRF  |= (1<<7);
            PORTF &= ~(1<<7);
            break;
        case 2:
            DDRB  |= (1<<6);
            PORTB &= ~(1<<6);
            break;
        case 3:
            DDRB  |= (1<<5);
            PORTB &= ~(1<<5);
            break;
        case 4:
            DDRB  |= (1<<4);
            PORTB &= ~(1<<4);
            break;
    }
}

keymap_common.h
Code: [Select]
/*
Copyright 2012,2013 Jun Wako <wakojun@gmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_COMMON_H
#define KEYMAP_COMMON_H

#include <stdint.h>
#include <stdbool.h>
#include <avr/pgmspace.h>
#include "keycode.h"
#include "action.h"
#include "action_macro.h"
#include "report.h"
#include "host.h"
#include "print.h"
#include "debug.h"
#include "keymap.h"


extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];


/* GH60 keymap definition macro
 * K2C, K31 and  K3C are extra keys for ISO
 */
#define KEYMAP( \
    K00, K01, K02, K03, \
    K10, K11, K12, K13, \
    K20, K21, K22, K23, \
    K30, K31, K32, K33, \
    K40, K41, K42, K43 \
)   { \
    { KC_##K00, KC_##K01, KC_##K02, KC_##K03 }, \
    { KC_##K10, KC_##K11, KC_##K12, KC_##K13 }, \
    { KC_##K20, KC_##K21, KC_##K22, KC_##K23 }, \
    { KC_##K30, KC_##K31, KC_##K32, KC_##K33 }, \
    { KC_##K40, KC_##K41, KC_##K42, KC_##K43 }  \
}

/* ANSI valiant. No extra keys for ISO */
#define KEYMAP_ANSI( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,      K2D, \
    K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B,           K3D, \
    K40, K41, K42,           K45,                     K4A, K4B, K4C, K4D  \
) KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, NO,  K2D, \
    K30, NO,  K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, NO,  K3D, \
    K40, K41, K42,           K45,                NO,  K4A, K4B, K4C, K4D  \
)


#define KEYMAP_HHKB( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K49,\
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,      K2D, \
    K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B,      K3D, K3C, \
    K40, K41, K42,           K45,                     K4A, K4B, K4C, K4D  \
) KEYMAP( \
    K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
    K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
    K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, NO,  K2D, \
    K30, NO,  K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
    K40, K41, K42,           K45,                K49, K4A, K4B, K4C, K4D  \
)

#endif

keymap_poker.c
Code: [Select]
#include "keymap_common.h"

const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 /* 0: Erster */
 KEYMAP(F1, F2, F3, F4, \
        7,  8,  9, END, \
4,  5,  6, PAUS, \
1,  2,  3,  UP, \
DOT, LEFT, DOWN, RGHT),

};

const uint16_t PROGMEM fn_actions[] = {};

                   Model M '88    | Model M SSK '87 | HHKB P2  | Zowie FK1

Offline 3K

  • Thread Starter
  • Posts: 279
  • Location: Germany
Re: Issue with hand-wired numpad
« Reply #5 on: Sat, 22 August 2015, 16:48:49 »
Bumping. I'm kinda desperated.  :-X

                   Model M '88    | Model M SSK '87 | HHKB P2  | Zowie FK1

Offline suicidal_orange

  • * Global Moderator
  • Posts: 4771
  • Location: England
Re: Issue with hand-wired numpad
« Reply #6 on: Sun, 23 August 2015, 04:35:04 »
It would be helpful to know which 3 characters are repeated, I bet it's actually 4 and you just can't see the pause or end, or maybe F3 and down...

Also please can you post a pic of your wiring?  Your grid matches the source so it must be a problem there :)
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline 3K

  • Thread Starter
  • Posts: 279
  • Location: Germany
Re: Issue with hand-wired numpad
« Reply #7 on: Sun, 23 August 2015, 05:57:44 »
It would be helpful to know which 3 characters are repeated, I bet it's actually 4 and you just can't see the pause or end, or maybe F3 and down...

Also please can you post a pic of your wiring?  Your grid matches the source so it must be a problem there :)

The characters repeated are 7, 8 and F1, causing my computer to open the help menu and filling its search bar with a stream of 78 on plug in. The F1 switch looked kinda bad after soldering so I checked how it looked on the inside, also used a new diode on this switch.

Edit: I just checked the board again with Aquakeytest and it's actually inputting F1, F2, F3, F4, 7 and 8 repeately.






Thanks for your help and time!
« Last Edit: Sun, 23 August 2015, 06:01:13 by 3K »

                   Model M '88    | Model M SSK '87 | HHKB P2  | Zowie FK1

Offline suicidal_orange

  • * Global Moderator
  • Posts: 4771
  • Location: England
Re: Issue with hand-wired numpad
« Reply #8 on: Sun, 23 August 2015, 06:28:24 »
Soldering looks fine, diodes are correct, no shorts... That means either the wires to the Teensy are not what you say/think they are, or it's a firmware issue but it's so tidy that I'm not going to question your wiring.

I don't know TMK but from reading the source it looks like you're reading 4 values while your diodes are setup that you scan the columns so you need to read back the 5 rows.  Maybe you need to swap your rows and columns in the config?

I'm going off to read about TMK, I keep meaning to but now I have a reason as what you're seeing doesn't make any sense by my understanding :))
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline 3K

  • Thread Starter
  • Posts: 279
  • Location: Germany
Re: Issue with hand-wired numpad
« Reply #9 on: Sun, 23 August 2015, 08:19:43 »
I don't know TMK but from reading the source it looks like you're reading 4 values while your diodes are setup that you scan the columns so you need to read back the 5 rows.  Maybe you need to swap your rows and columns in the config?

Actually I just edited the existing source code, which was written for boards with more coloumns than rows - could this be the problem? I'm not sure if it is possible to simply swap rows and cals like this.

                   Model M '88    | Model M SSK '87 | HHKB P2  | Zowie FK1

Offline suicidal_orange

  • * Global Moderator
  • Posts: 4771
  • Location: England
Re: Issue with hand-wired numpad
« Reply #10 on: Sun, 23 August 2015, 08:35:47 »
I've just done some reading - TMK works nothing like I thought!  Your code still looked ok though so I had a look at the GH60 PCB which uses TMK and on that the diodes are attached to the columns, not the rows.

I still don't fully understand it but your board looks a lot like the one detailed in the post dated 17 Apr 2014, 02:32 in this thread which Hasu replied that the columns and rows are reversed, so seems you do need to swap them.

Don't forget to rotate your layout too!
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline tlem

  • Posts: 20
Re: Issue with hand-wired numpad
« Reply #11 on: Sun, 23 August 2015, 08:36:47 »
Fix unselect_rows.  It needs port B assignments.

Offline 3K

  • Thread Starter
  • Posts: 279
  • Location: Germany
Re: Issue with hand-wired numpad
« Reply #12 on: Sun, 23 August 2015, 10:09:05 »
I've just done some reading - TMK works nothing like I thought!  Your code still looked ok though so I had a look at the GH60 PCB which uses TMK and on that the diodes are attached to the columns, not the rows.

I still don't fully understand it but your board looks a lot like the one detailed in the post dated 17 Apr 2014, 02:32 in this thread which Hasu replied that the columns and rows are reversed, so seems you do need to swap them.

Don't forget to rotate your layout too!

Fix unselect_rows.  It needs port B assignments.

Okay so I followed tlems advice first - I actually unselected the cols, instead of the rows.

After changing this, recompiling and reflashing the board has stopped inputting random things.

Fixed matrix.c:
Code: [Select]
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * scan matrix
 */
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"


#ifndef DEBOUNCE
#   define DEBOUNCE 5
#endif
static uint8_t debouncing = DEBOUNCE;

/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];

static matrix_row_t read_cols(void);
static void init_cols(void);
static void unselect_rows(void);
static void select_row(uint8_t row);


inline
uint8_t matrix_rows(void)
{
    return MATRIX_ROWS;
}

inline
uint8_t matrix_cols(void)
{
    return MATRIX_COLS;
}

void matrix_init(void)
{
    // initialize row and col
    unselect_rows();
    init_cols();

    // initialize matrix state: all keys off
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
        matrix[i] = 0;
        matrix_debouncing[i] = 0;
    }
}

uint8_t matrix_scan(void)
{
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        select_row(i);
        _delay_us(30);  // without this wait read unstable value.
        matrix_row_t cols = read_cols();
        if (matrix_debouncing[i] != cols) {
            matrix_debouncing[i] = cols;
            if (debouncing) {
                debug("bounce!: "); debug_hex(debouncing); debug("\n");
            }
            debouncing = DEBOUNCE;
        }
        unselect_rows();
    }

    if (debouncing) {
        if (--debouncing) {
            _delay_ms(1);
        } else {
            for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
                matrix[i] = matrix_debouncing[i];
            }
        }
    }

    return 1;
}

bool matrix_is_modified(void)
{
    if (debouncing) return false;
    return true;
}

inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
    return (matrix[row] & ((matrix_row_t)1<<col));
}

inline
matrix_row_t matrix_get_row(uint8_t row)
{
    return matrix[row];
}

void matrix_print(void)
{
    print("\nr/c 0123456789ABCDEF\n");
    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
        phex(row); print(": ");
        pbin_reverse16(matrix_get_row(row));
        print("\n");
    }
}

uint8_t matrix_key_count(void)
{
    uint8_t count = 0;
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        count += bitpop16(matrix[i]);
    }
    return count;
}

/* Column pin configuration
 * col: 0   1   2   3
 * pin: F0  F1  F4  F5   (Rev.A)
 * pin:                  (Rev.B)
 */
static void  init_cols(void)
{
    // Input with pull-up(DDR:0, PORT:1)
    DDRF  &= ~(1<<0 | 1<<1 | 1<<4 | 1<<5);
    PORTF |=  (1<<0 | 1<<1 | 1<<4 | 1<<5);
   
}

static matrix_row_t read_cols(void)
{
    return (PINF&(1<<0) ? 0 : (1<<0)) |
           (PINF&(1<<1) ? 0 : (1<<1)) |
           (PINF&(1<<4) ? 0 : (1<<2)) |
           (PINF&(1<<5) ? 0 : (1<<3))
;
}

/* Row pin configuration
 * row: 0   1   2   3   4
 * pin: F6  F7  B6  B5  B4
 */
static void unselect_rows(void)
{
    // Hi-Z(DDR:0, PORT:0) to unselect
    //DDRF  &= ~0b00110011;
    //PORTF &= ~0b00110011;
DDRF  &= ~0b011000000;
    PORTF &= ~0b011000000;
DDRB  &= ~0b011100000;
    PORTB &= ~0b011100000;
}

static void select_row(uint8_t row)
{
    // Output low(DDR:1, PORT:0) to select
    switch (row) {
        case 0:
            DDRF  |= (1<<6);
            PORTF &= ~(1<<6);
            break;
        case 1:
            DDRF  |= (1<<7);
            PORTF &= ~(1<<7);
            break;
        case 2:
            DDRB  |= (1<<6);
            PORTB &= ~(1<<6);
            break;
        case 3:
            DDRB  |= (1<<5);
            PORTB &= ~(1<<5);
            break;
        case 4:
            DDRB  |= (1<<4);
            PORTB &= ~(1<<4);
            break;
    }
}


The test with Aquakeytest shows that the whole board is mirrored and every key in the last row inputs the whole coloumns. Slowly improving!

                   Model M '88    | Model M SSK '87 | HHKB P2  | Zowie FK1

Offline 3K

  • Thread Starter
  • Posts: 279
  • Location: Germany
Re: Issue with hand-wired numpad
« Reply #13 on: Tue, 25 August 2015, 10:40:03 »
Sooo I fixed the row selection and mirrored the keymap - now everything works fine! Thanks to everyone who helped me.

If anyone cares, that's the little guy I'm talking about:



Yes, the cable needs an other positioning, but I have no extension and didn't want to ruin my only mini USB cable.

                   Model M '88    | Model M SSK '87 | HHKB P2  | Zowie FK1