/*自作フットスイッチ
フットスイッチ...足で操作するキーボード 今回は4つを使う
ハードウェア
・ElegooUnoR3(ATmega16U2)
・タクトスイッチ×5(足元4スイッチ+手元1スイッチ)
モード
・0 game F6/F7/F8/F9
・1 text tab/backspace/space/enter
特殊モード
・自動起動BOT
・放置BOT(短時間)
・放置BOT(長時間)
スイッチ
・足は左から LO LC RC RO,手はHに呼称を統一する
※送信内容やモード数を変えたい場合は func_arysetupのみ弄る
わざわざそのためにプログラム側に柔軟性を持たせ、その結果複雑になってデバッグもめんどいことになったのに、
仕様変更のために別のとこをいじくり回してぶっ壊してデバッグし直しはあまりにも馬鹿馬鹿しい */
/* ショートカット 初期設定:dfu-setup 通常:dfu-def キーボード:dfu-key
sudo su
cd /home/antares/Arduino
通常 dfu-programmer atmega16u2 erase ; dfu-programmer atmega16u2 flash UNO-dfu_and_usbserial_combined.hex
キーボード dfu-programmer atmega16u2 erase ; dfu-programmer atmega16u2 flash Arduino-keyboard-0.3.hex */
//配列,定数,変数宣言
//変数
uint8_t ary_pin_sta [5][2] = {{0,0},{0,0},{0,0},{0,0},{0,0}}; //2次元配列を宣言 5ピン×(1平均+1前回)
uint16_t ary_buffer_def [4] = {0,0,0,0}; //8byte
uint8_t ary_buffer_spe [8] ={0,0,0,0,0,0,0,0};
uint8_t var_mode_now = 0; //現在のモード番号
uint16_t ary_ser[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //送信内容の配列
//定数 ここで初期化も
uint16_t ary_keylist_spe [8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//修飾キー
const uint8_t var_mode_pieces = 2; //モード数
//定数 可読性のために別関数で初期化予定
uint8_t ary_pin_number [5]; //ピン番号 LO,LC,RC,RO,Hの順
uint16_t ary_keylist [3][4][2]; //3次元配列を宣言 3モード×4スイッチ×2送信枠(0はCtrlを使うか、1はキーコード)
uint16_t ary_mode_name [3][var_mode_pieces]; //モード数×モード名の文字数
void setup () {
Serial.begin ( 9600 );
delay (2000); //PC側の認識待機時間 不必要な気もするが一応残す
func_arysetup (); //定数配列の初期化
for (uint8_t i=0; i < 5 ; i++) { //ピンモード設定
pinMode( ary_pin_number [i], INPUT_PULLUP);
}
uint8_t tmp_ctr = 0;
while(ary_mode_name [var_mode_now] [tmp_ctr] != 0x00) { //モード名送信
ary_ser[2] == ary_mode_name [var_mode_now] [tmp_ctr];
func_ser(1,1);
tmp_ctr ++;
}
}
void loop () {
func_pin(); //ピン読み "ary_pin_sta[n(0~4)][0]"が戻り値代わり
uint8_t var_fork = func_fork;
switch (var_fork) { //debug caseの関数は全て未定義!!特殊モード切替と通常モード切替の操作方法を逆転?ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
case 0: //通常送信
func_send();
break;
case 1: //LO
var_mode_now = 0; //ショートカットモード
break;
case 2: //LC
var_mode_now = 1; //テキスト編集モード
break;
case 3: //RC
func_mode_spe();
break;
case 4: //RO
func_mode_spe();
break;
}
func_resetup(); //どれが呼び出されてもリセットする 必要かは分からないが一応
delay (10);
}
void func_ser (uint8_t ser_0,uint8_t ser_rst) { //シリアル送信関数 リセットか(0がリセット)/送信後にリセットするか(1でリセット) 送信内容は引数モドキのary_ser
if (ser_0 == 0) {
for(uint8_t i = 0; i<8; i++) {
Serial.write(0x00);
}
} else if (ser_0 == 1){
for(uint8_t i = 0; i<8; i++) {
Serial.write(ary_ser[i]);
}
if(ser_rst == 1 ) {
func_ser(0,0); //リセットする/再リセットしない という設定で自己呼び出し
}
}
for(uint8_t i = 0; i<8; i++) { //送信配列リセット
ary_ser[i] = 0;
}
}
void func_arysetup () { //定数配列設定
//ピン番号
ary_pin_number [0] = 8; //LO
ary_pin_number [1] = 9; //LC
ary_pin_number [2] = 10; //RC
ary_pin_number [3] = 11; //RO
ary_pin_number [4] = 12; //H
//モード名 モード名の最後に0x00を入れる
//モード0 game →Fkeyに変える できれば0byteを使いたい→改変
ary_mode_name [0] [0] = 0x0A;
ary_mode_name [0] [1] = 0x04;
ary_mode_name [0] [2] = 0x10;
ary_mode_name [0] [3] = 0x08;
ary_mode_name [0] [4] = 0x00;
//モード1 text →TxtEditに変える 上に同じ
ary_mode_name [1] [0] = 0x17;
ary_mode_name [1] [1] = 0x08;
ary_mode_name [1] [2] = 0x1B;
ary_mode_name [1] [3] = 0x17;
ary_mode_name [1] [4] = 0x00;
//キーコードリスト [n][n][0]をctrl使用かではなく使用する修飾キーのbyte数(1スタートで指定)
//debug 欠陥発見!!! Lctrlも修飾キー不使用も、どっちも0になってる!
/* 修飾キーの指定リスト ※不使用との区別のため+1する
1 L ctrl
2 L shift
3 L alt
4 L super
5 R ctrl
6 R shift
7 R alt
8 R super
*/
//モード0 F6/F7/F8/F9
ary_keylist [0] [0] [0] = 0;
ary_keylist [0] [0] [1] = 0x3F;
ary_keylist [0] [1] [0] = 0;
ary_keylist [0] [1] [1] = 0x40;
ary_keylist [0] [2] [0] = 0;
ary_keylist [0] [2] [1] = 0x41;
ary_keylist [0] [3] [0] = 0;
ary_keylist [0] [3] [1] = 0x42;
//モード1 tab/backspace/space/enter
ary_keylist [1] [0] [0] = 0;
ary_keylist [1] [0] [1] = 0x2B;
ary_keylist [1] [1] [0] = 0;
ary_keylist [1] [1] [1] = 0x2a;
ary_keylist [1] [2] [0] = 0;
ary_keylist [1] [2] [1] = 0x2c;
ary_keylist [1] [3] [0] = 0;
ary_keylist [1] [3] [1] = 0x58;
}
void func_pin () { //ピン読み 戻り値代わりはary_pin_sta
for (uint8_t i=0; i < 5 ; i++) {
if (digitalRead (ary_pin_number[i]) == LOW ) {
ary_pin_sta [i] [0] = 1;
}
}
}
uint8_t func_fork () { //分岐処理 switch用に戻り値を返す 0=通常送信 1=LO 2=LC 3=RC 4=RO
if(ary_pin_sta[4][0] != ary_pin_sta[4][1] &&ary_pin_sta[4][0] ==1 ){
uint8_t var_return = func_fork_mode + 1;
return var_return;
}else if(ary_pin_sta[4][0] != ary_pin_sta[4][1]){
//スルー
} else {
return 0; //通常送信
}
}
uint8_t func_fork_mode () { //モード分岐の条件
while(func_fork_mode_condition == 0) { //全てのキーが離されるまで待機
//なにもしない
}
while ( func_fork_mode_condition == 0 ) { //キーが押されるまでループ returnは押されたキー番号
func_pin ();
for(uint8_t i =0;i<4;i++) {
if(ary_pin_sta[i] ==1) {
return [i];
}
}
}
}
uint8_t func_fork_mode_condition () { //全て(※ハンドキーを除く)のピンが押されていないかを返す returnは1つも押されていない場合のみ0になる
uint8_t condition_ctr = 0;
for(uint8_t i = 0; i < 4; i++ ) {
if(digitalRead (ary_pin_number[i]) == LOW) {
condition_ctr = 1;
}
}
if ( condition_ctr == 1 ) {
return 1;
} else {
return 0;
}
}