Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 1 of 1

Thread: Help with Teensy2 Layered Keyboard Firmware, Esp the Scanning and Press Sending Parts

  1. #1
    Junior Member
    Join Date
    Jun 2014
    Posts
    1

    Help with Teensy2 Layered Keyboard Firmware, Esp the Scanning and Press Sending Parts

    TL;DR
    • Code for scanning of an irregularly shaped matrix
    • Code for sending key presses to a computer
    • Do I need to do anything to prepare for the event of disconnecting the cable(cutting the power) like resetting/saving any variables etc?
    • Is my timer related code implemented correctly/is there a better way to do it?
    • Please suggest any miscellaneous performance improvements/bugfixes you think could be made

    Hello and thanks for any help you may be able to provide! To start off with, the key-switches are Cherry MX Blues. Second, the matrices( both the full one and the simplified prototype one in the code) are irregularly shaped. Would this affect any suggested matrix scanning algorithms? Uniquely, the keyboard is built around the concept of layer keys which determine the output of regular keys. Furthermore, modifier and layer keys are sticky. A single tap toggles activity, while a double tap locks it active. Only one layer at a time can be active, but multiple modifiers can be active. Contrastingly, regular keys are not sticky, but will produce output only when held down. I'm not sure how to implement this holding behavior, or if it should go into the press sending or key type related if statements.

    On to the code! This code doesn't include my full keymap and is lacking code for detecting physical key presses(matrix scanning) and sending output to a computer. Also, some variables in the structs are unused. I will probably take them out at some point. I'll also attach images of my schematic, PCB, and the full map I eventually plan to have below. The full map may change and is slightly out of date(a layer key is missing).

    Code:
    int currentLayer=0;
     bool LayerPermDown=false;// for double taps
     uint_16t doubleTapTime=250;
     uint_4t howManyMods=2
     
     typedef struct regKey {
     	uint_2t keyType;//needed because c it doesn't support runtime type checking, one equals regular 2 equals layer and three equals mod
     	uint_4t keyRow; //check if this type is available
     	uint_4t keyCol; //check if availible
     	char layerZeroVal;//always default layer
     	char layerOneVal;
     	char layerTwoVal;
     	bool isPhysDown;
     	//Possibly replace keycol and keyrow with a two-dimensional array
     //containing pointers to each key object in physical keypress
     //function this would be put in parentheses turkeys that don't
     //exist such as when a row/column combination does not have a
     //key there simply use a dummy value or variable that means nothing
     };
    
     typedef struct layKey {
     	uint_2t keyType;//needed because c it doesn't support runtime type checking, one equals regular 2 equals layer and three equals mod
     	uint_4t keyRow; //check if this type is available
     	uint_4t keyCol; //check if availible
     	int layerNum;
     	elapsedMillis timeElapsed;
     	bool isPhysDown;
    	bool isVirtDown;
    };
    
    typedef struct modKey {
     	uint_2t keyType;//needed because c it doesn't support runtime type checking, one equals regular 2 equals layer and three equals mod
     	uint_4t modNumber;
    	//need to add string for conversion to propper hex val when sending (eg alt, opt, ctl etc.)
     	uint_4t keyRow; //check if this type is available
     	uint_4t keyCol; //check if availible
     	bool isPermDown;
     	elapsedMillis timeElapsed;
     	bool isPhysDown;
    	bool isVirtDown;
    }
    
    regKey key5 = {1,0,2,"v","a","b",false};
    regKey key6 = {1,0,3,"x","c","d",false};
    regKey key7 = {1,0,4,"y","e","f",false};
    regKey key8 = {1,1,5,"z","g","h",false};
    modKey key3={3,1,2,0,0,false,false};
    modKey key4={3,0,2,2,0,0,false,false};
    layKey key1={2,1,1,1,1,0,false,false};
    layKey key2={2,2,1,2,0,false,false};
    
    bool modNormDown[howManyMods]={false};
    bool modPermDown[howManyMods]={false};
    //PROTOTYPE MAP FOR THIS CODE
    //|---------------------|
    //|key1key3 key5key6key7|
    //|key2key4---------key8|
    
    void cleanup() {
    	if(!layerPermDown) {
    		currentLayer=0;
    	}
    	for(i = 0; i < howManyMods; i++)
    	{
    	 	if(modNormDown[pressedKey.modNum]==true && modPermDown[pressedKey.modNum]==false) {
    				modNormDown[pressedKey.modNum]=false;
    			
    		}
    	}
    
    }
    //addfunc
    if (pressedkey.keyType==1) {
    	//send char for active layer
    	cleanup();
    }
    else if (pressedkey.keyType==2) {
    	if (currentLayer!=pressedKey.layerNum) {
    		//start timer for this key
    		layerPermDown=false;
    		currentLayer=pressedKey.layerNum;
    	}
    	else {
    		if (pressedKey.elapsedMillis<doubleTapTime) {
    			pressedKey.elapsedMillis=0;
    			layerPermDown=true;
    		}
    		else if (layerPermDown==true || pressedKey.elapsedMillis>=doubleTapTime)
    			pressedKey.elapsedMillis=0;
    			layerPermDown=false;
    			currentLayer=0;
    			
    	}
    }
    
    else if (pressedkey.keyType==3) {
    	if (modNormDown[pressedKey.modNum]==false && modPermDown[pressedKey.modNum]==false) {
    		//start timer for this key
    		pressedKey.elapsedMillis=0;
    		modNormDown[pressedKey.modNum]=true;
    		
    	}
    	else {
    		if (modNormDown[pressedKey.modNum]==true && pressedKey.elapsedMillis<doubleTapTime) {
    			pressedKey.elapsedMillis=0;
    			modPermDown[pressedKey.modNum]=true;
    		}
    		else if (layerPermDown==true || pressedKey.elapsedMillis>=doubleTapTime) {
    			pressedKey.elapsedMillis=0
    			modPermDown[pressedKey.modNum]=false;
    			modNormDown[pressedKey.modNum]=false;
    		}
    	}
    }


    map:
    Attachment 2269

    schematic:
    Attachment 2271

    pcb
    Attachment 2270


    To recap, I need help with the following:
    • Code for scanning of an irregularly shapped matrix
    • sending keypresses to a computer
    • Do I need to do anything to prepare for the event of disconnecting the cable(cutting the power) like reseting/saving any variables etc
    • Is my timer related code implemented correctly/ is there a better way to do it
    • Please suggest any miscleanious performance improvements/bugfixes you think could be made
    Last edited by fozbstudios; 06-26-2014 at 02:21 AM. Reason: corrected two typos

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •