Qmk_firmware: [Question] Is `pin_to_mux[]` table in `analog.c` for `analogRead()` correct?

Created on 18 Jan 2018  Β·  7Comments  Β·  Source: qmk/qmk_firmware

Summary

I wonder that a pin_to_mux[] table in analog.c was NOT suitable for Pro Micro with AVR ATmega32U4.

πŸ‘ŒπŸ‘ŒπŸ‘ŒπŸ‘Œ Expected πŸ‘ŒπŸ‘ŒπŸ‘ŒπŸ‘Œ

  1. Source:

    1. New keyboard from template, and initialize for debugging.
    2. Add below lines in default/keymap.c

      #include "pro_micro.h"
      #include "analog.h"
      #include "print.h"
      

      and

      static void print_analog_pins(void) {
        int16_t val = analogRead(A0);
        print("  A0:"); print_dec(A0);
        print(" val:"); print_decs(val); println();
      }
      
      #define PRINT_INTERVAL 5000
      void matrix_scan_user(void) {
        static int16_t counter = PRINT_INTERVAL;
        counter++;
        if (PRINT_INTERVAL < counter) {
          print_analog_pins();
          counter = 0;
        }
      }
      
    3. Add below lines in ruels.mk

      SRC += analog.c
      
    4. Build source and transfer into Pro Micro.
  2. Schematic:

    • VCC -> R1(10kOhm) -> GND

    • case 1: Pin A0 to GND

    • case 2: Pin A0 to VCC

Result: case 1

A0:0 val:1023

or case 2

A0:0 val:0

Sounds good πŸ‘ŒπŸ‘ŒπŸ‘ŒπŸ‘Œ

πŸ’©πŸ’©πŸ’©πŸ’© Actual πŸ’©πŸ’©πŸ’©πŸ’©

Results: case 1,2

A0:0 val:(at random)

Oh, 😒 ...

πŸ’» An adhoc-patch

in analog.c:

 {
 #if defined(__AVR_ATmega32U4__)
    static const uint8_t PROGMEM pin_to_mux[] = {
-       0x00, 0x01, 0x04, 0x05, 0x06, 0x07,
-       0x25, 0x24, 0x23, 0x22, 0x21, 0x20};
+       0x07, 0x06, 0x05, 0x04, 0x01, 0x00,
+       0x20, 0x22, 0x23, 0x24, 0x24, 0x21};

πŸ“„ The circumstances

When I wrote Arduino sketch for trying an Analog Stick, I have no problem. But, I have problems when I am trying same things on qmk, This issue is one of them.

πŸ“š References

help wanted question

All 7 comments

@jackhumbert? Or should somebody else be tagged here?

I started making a dual joystick mouse with a pro micro and ran into the same issue. I managed to debug the signal of the pins to find the corresponding integers just to get it working. The ad-hoc patch given here also works for me.

This is my first attempt at making something custom with QMK, so I'm not sure what the correct solution is, but I'd love to see this resolved.

I think there may have been a change recently that handles this better, but I'm not sure about that.

I started making a dual joystick mouse with a pro micro and ran into the same issue. I managed to debug the signal of the pins to find the corresponding integers just to get it working. The ad-hoc patch given here also works for me.

This is my first attempt at making something custom with QMK, so I'm not sure what the correct solution is, but I'd love to see this resolved.

Hi John. Do you happen to have schematics for your dual joystick mouse? I have your mousepad branch's keymap compiled, a pro micro, & some joysticks. Would really like to try it out.

Hey πŸ‘‹ ,

  1. You missed 0x25, and have a duplicate 0x24 is your patch in the first comment.
  2. Why follow the pin order of the pro micro in particular ?

have a great day (:

analogRead is modeled after Arduino and Arduino Micro uses the following assignment. Pro Micro mostly follows the Arduino Micro’s pin naming, except that it exposes fewer pins.

|Arduino|Atmega32u4|ADC|MUX|
|-------|----------|---|---|
|A0|F7|7|7|
|A1|F6|6|6|
|A2|F5|5|5|
|A3|F4|4|4|
|A4|F1|1|1|
|A5|F0|0|0|
|A6=D4|D4|8|0x20|
|A7=D6|D7|10|0x22|
|A8=D8|B4|11|0x23|
|A9=D9|B5|12|0x24|
|A10=D10|B6|13|0x25|
|A11=D12|D6|9|0x21|

Arguably, that is not a good API either, because you have to use an Atmega32u4 pin name for a setPinInput call in the init function, and whichever analog pin index selects the correct mux for an analogRead in the scan function. As a QMK user, I think I would much prefer to just use the same Atmega32u4 pin names (F7, F6, F5, F4, F1, F0, D4, D7, B4, B5, B6, D6) in both places.

// renamed to communicate semantic difference from Arduino
int16_t analogPinRead(uint8_t pin)
{
#if defined(__AVR_ATmega32U4__)
    uint8_t mux;
    switch (pin) {
    case F7: mux = 7; break;
    case F6: mux = 6; break;
    // …
    case D6: mux = 0x21; break;
    default: return 0;
    }
    return adc_read(mux);

Is there a PR open for this? I can't seem to find it. If not, we should probably make one.

Was this page helpful?
0 / 5 - 0 ratings