Unable to set the led colors using ColorMap on Model100

Hi:

I have been using the Keyboardio model01 for a long time, and I just got one of my two Model 100. I tried to use the same firmware for the model100 that I had with my model 01, but I had a few plugins on my arduino installation. I though I had bricked my keyboardio but reinstalling the firmware from Chrysalis fixed the issue. I decided to perform a brand-new install of Arduino, and the current version of the IDE I have is 2.0.
Long story short, I’m re-writing the layout based on the example code that you get when you install arduino from scratch and add the model100 as the board.

Everything was working ok, until I got to the leds. For some reason, there seems to be a problem when I try to use the example from ColorMap. I cannot make this one work by itself.

I am also having problems with the interactions between OneShot, ActiveModColor, TopsyTurvy, Macros, MagicCombo, and NumPad. The keys work fine, but the leds behave very strangly: pressing the OSL(Numpad) key causes the keys on the number pad to go dark.

For some reason, all keys other than the top row on both hands are red, as well as the second inner key on the thumb cluster.

I realize this may be a problem on the order of initialization of the different plugins. If you happen to use Kaleidoscope to program your model 100, and you have a solution for this issue, could you let us know?

Could you share your sketch, please? Would make it easier to glance it over and see if I can spot anything.

/*

MUST USE keyboardio GD32 version 1.99.6 and Arduino 
Version: 2.0.0
Date: 2022-09-14T07:06:37.759Z
CLI Version: 0.27.1 [a900cfb2]

Color of leds are wrong.
Mostly red, except top row, windows key, palm buttons 
and all but second outer thunb key.
NumPad turns off leds, and FUNCTION leaves C(j), Enter, and ,(v) 
keys lit, turning everything else off.

Copyright © 2022 Arduino SA
*/

/* -*- mode: c++ -*-
 * Basic -- A very basic Kaleidoscope example
 * Copyright (C) 2018  Keyboard.io, Inc.
 *
 * 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, version 3.
 *
 * 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/>.
 */

#include <Kaleidoscope.h>

// Support for controlling the keyboard's LEDs
#include <Kaleidoscope-LEDControl.h>

// Show status of mod buttons
#include <Kaleidoscope-LED-ActiveModColor.h>

// allow one shot
#include <Kaleidoscope-OneShot.h>

// Support for "Numpad" mode, which is mostly just the Numpad specific LED mode
#include "Kaleidoscope-NumPad.h"

// Support for keys that move the mouse
#include "Kaleidoscope-MouseKeys.h"

// Support for macros
#include "Kaleidoscope-Macros.h"

#include <Kaleidoscope-MagicCombo.h>

#include <Kaleidoscope-TopsyTurvy.h>

enum {
     MACRO_USER,  
     MACRO_VERSION_INFO,
      //  OSMALTCTRL,
//       MACRO_PASS,
//     MACRO_PASS2,
//	 MACRO_ANY,
     MACRO_FCDOWN,
     MACRO_FCUP
};

enum {
  PRIMARY,
  NUMPAD,
  FUNCTION,
};  // layers

static void user(uint8_t keyState){
  if(keyToggledOn(keyState)){
	  Macros.type(PSTR("username"));
  }
}
static void versionInfoMacro(uint8_t key_state) {
  if (keyToggledOn(key_state)) {
    Macros.type(PSTR("Keyboardio Model 100 - Firmware version "));
    Macros.type(PSTR(KALEIDOSCOPE_FIRMWARE_VERSION));
  }
}

static void pass(uint8_t keyState){
    Macros.type(PSTR("Password"));
}

static void pass2(uint8_t keyState) {
  Macros.type(PSTR("Password2"));
}

static void pass3(uint8_t keyState){
  Macros.type(PSTR("Password3"));
}

/** anyKeyMacro is used to provide the functionality of the 'Any' key.
 *
 * When the 'any key' macro is toggled on, a random alphanumeric key is
 * selected. While the key is held, the function generates a synthetic
 * keypress event repeating that randomly selected key.
 *
 */

static void anyKeyMacro(KeyEvent &event) {
  if (keyToggledOn(event.state)) {
    event.key.setKeyCode(Key_A.getKeyCode() + (uint8_t)(millis() % 36));
    event.key.setFlags(0);
  }
}


/** Magic combo list, a list of key combo and action pairs the firmware should
 * recognise.
 */
USE_MAGIC_COMBOS(
  // {.action = toggleKeyboardProtocol,
  //                 // Left Fn + Esc + Shift
  //                 .keys = { R3C6, R2C6, R3C7 }
  //                }
 				//  ,
                 {.action = pass,
                 // both function buttons and the prog key together
                 .keys = {R3C6, R3C9, R0C0}
                 }
				 ,
         
				 {.action = pass2,
				// both function buttons and the num key together
				 .keys = {R3C6, R3C9, R0C15}
				 }
 				 /*
				 ,
				 {.action = pass3,
				 // both function buttons and the any key together
				 .keys = {R3C6, R3C9,R0C9}
				 } 
          */
                 );

// clang-format off
KEYMAPS(
  [PRIMARY] = KEYMAP_STACKED
  (___,       TOPSY(1),      TOPSY(2),  TOPSY(3),   TOPSY(4), TOPSY(5), Key_LEDEffectNext,
   Key_Backtick, Key_Quote,     Key_Comma, Key_Period, Key_P, Key_Y, Key_Tab,
   Key_PageUp,   Key_A,         Key_O,     Key_E,      Key_U, Key_I,
   Key_PageDown, Key_Semicolon, Key_Q,     Key_J,      Key_K, Key_X, Key_Escape,
   OSM(LeftControl), Key_Backspace, OSM(LeftShift), OSM(LeftGui),
   OSL(NUMPAD),

   M(MACRO_USER),   TOPSY(6), TOPSY(7), TOPSY(8), TOPSY(9), TOPSY(0), LockLayer(NUMPAD),
   Key_Enter,      Key_F, Key_G, Key_C, Key_R, Key_L, Key_Slash,
                   Key_D, Key_H, Key_T, Key_N, Key_S, Key_Minus,
   OSM(RightGui),   Key_B, Key_M, Key_W, Key_V, Key_Z, Key_Equals,
   OSM(LeftAlt), OSM(LeftShift), Key_Spacebar, OSM(LeftControl),
   OSL(FUNCTION)),
     
  [NUMPAD] =  KEYMAP_STACKED
  (___, ___, ___, ___, ___, ___, ___,
   ___, ___, ___, ___, ___, ___, ___,
   ___, ___, ___, ___, ___, ___,
   ___, ___, ___, ___, ___, ___, ___,
   ___, ___, ___, ___,
   ___,

   ___,                    ___, Key_7, Key_8,   Key_9,        Key_KeypadSubtract, ___,
   ___,                    ___, Key_4, Key_5,   Key_6,        Key_KeypadAdd,      ___,
                           ___, Key_1, Key_2,   Key_3,        Key_Equals,         ___,
   ___,                    ___, Key_0, Key_Period, Key_KeypadMultiply, Key_KeypadDivide,   Key_Enter,
   ___, ___, ___, ___,
   ___),

  [FUNCTION] =  KEYMAP_STACKED
  (___,      Key_F1,           Key_F2,      Key_F3,     Key_F4,        Key_F5,           Key_CapsLock,
   Key_Tab,  Key_mouseScrollUp,  Key_mouseUp, Key_mouseScrollDn,        Key_mouseBtnL, Key_mouseWarpEnd, Key_mouseWarpNE,
   Key_Home, Key_mouseL,       Key_mouseDn, Key_mouseR, Key_mouseBtnR, Key_mouseWarpNW,
   Key_End,  Key_PrintScreen,  Key_Insert,  ___,        Key_mouseBtnM, Key_mouseWarpSW,  Key_mouseWarpSE,
   ___, Key_Delete, ___, ___,
   ___,

   Consumer_ScanPreviousTrack, Key_F6,                 Key_F7,                   Key_F8,                   Key_F9,          Key_F10,          Key_F11,
   ___,    Consumer_ScanNextTrack, Key_LeftCurlyBracket,     Key_RightCurlyBracket,    Key_LeftBracket, Key_RightBracket, Key_F12,
                               Key_LeftArrow,          Key_DownArrow,            Key_UpArrow,              Key_RightArrow,  M(MACRO_FCDOWN),    M(MACRO_FCUP),
   Key_PcApplication,          Consumer_Mute,          Consumer_VolumeDecrement, Consumer_VolumeIncrement, ___,             Key_Backslash,    Key_Pipe,
   ___, ___, Consumer_PlaySlashPause, ___,
   ___)
)



/** macroAction dispatches keymap events that are tied to a macro
    to that macro. It takes two uint8_t parameters.

    The first is the macro being called (the entry in the 'enum' earlier in this file).
    The second is the state of the keyswitch. You can use the keyswitch state to figure out
    if the key has just been toggled on, is currently pressed or if it's just been released.

    The 'switch' statement should have a 'case' for each entry of the macro enum.
    Each 'case' statement should call out to a function to handle the macro in question.

 */

const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
  switch (macro_id) {
  case MACRO_USER:
 	  user(event.state);
    break;
  case MACRO_VERSION_INFO:
    versionInfoMacro(event.state);
    break;
	
//  case MACRO_ANY:
//	anyMacroKey(event.state);
//	break;

 case MACRO_FCUP:
//    kaleidoscope::plugin::LEDFunctionalColor::FunctionalColor::brightnessUp(keyState);
    break;
 case MACRO_FCDOWN:
//    kaleidoscope::plugin::LEDFunctionalColor::FunctionalColor::brightnessDown(keyState);
    break;
  }
  return MACRO_NONE;
}
// clang-format on

KALEIDOSCOPE_INIT_PLUGINS(
  LEDControl,
  LEDOff,
  ActiveModColorEffect,
    // The numpad plugin is responsible for lighting up the 'numpad' mode
  // with a custom LED effect
  NumPad,
  
  // Magic combo needs to be above Macros (I guess)
  MagicCombo,

  // The macros plugin adds support for macros
  Macros,

  // The MouseKeys plugin lets you add keys to your keymap which move the mouse.
  MouseKeys,

  OneShot,
  TopsyTurvy
)

void setup() {
  Kaleidoscope.setup();

  ActiveModColorEffect.setOneShotColor(CRGB(0x00, 0xff, 0x00));
  ActiveModColorEffect.setHighlightColor(CRGB(0x00, 0x00, 0xff));
  ActiveModColorEffect.setStickyColor(CRGB(0xff, 0x00, 0x00));
  ActiveModColorEffect.highlightNormalModifiers(true);

  // Uncomment the following to enable OneShot on normal modifier keys:
  OneShot.enableAutoOneShot();
}

void loop() {
  Kaleidoscope.loop();
}

Forgot to mention: I am selecting board as keyboardio GD32, version 1.99.6. If I try 1.99.5, I get no leds to turn on, and the key layout is nowhere close to what I planned, to the point that the function buttons were typing letters, and most keys would not type anything. I had to use Chrysalis to reset the keyboard to factory status before I could program it again.

Update: I think there is something that is not being updated properly on the led map when the keyboardio gets started.

I was able to use FuncionalColors (FunctionalColor v3 - Dynamically Label Active Keys with Colors), which is my favorite led plugin, and there is an interesting development now: when FunctionalColors is running, the keys that did not have leds on are now lit with the expected led colors. Even the brightness behave properly. When I switch to the function layer, the colors are correct. When I switch to the numeric layer, the keys that are redefined on that layer switch off.

I found out that removing NumPad from my sketch fixes my problems.

Are you able to share your config somewhere? I tried to use funccolor but no colors came out.

Final update (at least from me): the issue I had seems to have been a combination of trying to use NumPad, FunctionalColor, EEPROM, and Chrysalis. In the end, I went with not using NumPad. I was trying to keep EEPROM in use, but two thing happened: I could not get it to work properly with Chrysalis, and, more importantly, eventually the whole thing became too big for my model 01 to handle. In the process, I ended up editing the sample code to include lots of #define and #ifdef clauses, so now I can edit the top of the file and decide which features I want without having to worry about looking over the file. While I see the value for most people to use Chrysalis, some of the features I got used over the years (topsy-turvy, one-shot, activeModColors, Functional Colors) may not be easily replicated in Chrysalis alone.

I created a project in GitHub - lgnakano/KeyboardioSketches: Keyboardio Sketch where I keep my sketches (other than the private part of it) updated.