Ne pas oublier de mettre à jour la library de DCS-BIOS avec le bug que j'ai remonté ici : http://www.checksix-forums.com/viewtopi ... 1#p1612201
J'ai donc ajouter 2 classes :
Code : Tout sélectionner
namespace DcsBios {
class ErgoButton : PollingInput {
private:
const char* msg_;
bool (*callback_)(char)=0 ;
bool lastState_;
char key_;
void init_(const char* msg, bool (*callback)(char), char key) {
msg_ = msg;
callback_ = callback;
lastState_ = false;
key_ = key;
}
void pollInput() {
bool state = callback_(key_);
if (state != lastState_) {
if (tryToSendDcsBiosMessage(msg_, state == true ? "0" : "1")) {
lastState_ = state;
}
}
}
public:
ErgoButton(const char* msg, bool (*callback)(char),char key)
{
init_(msg, callback,key);
}
};
class ErgoKnob : PollingInput {
private:
const char* msg_;
int (*callback_)()=0 ;
int lastPos_;
void init_(const char* msg, int (*callback)()) {
msg_ = msg;
callback_ = callback;
lastPos_ = callback();
}
void pollInput()
{
int pos = callback_();
if (pos != lastPos_)
{
byte buff[] = " " ;
String(pos).getBytes(buff,3);
if (tryToSendDcsBiosMessage(msg_, buff) )
{
lastPos_ = pos;
}
}
}
public:
ErgoKnob(const char* msg, int (*callback)())
{
init_(msg, callback);
}
};
}
ErgoButton, permet d'interroger une fonction qui retourne vrai si le bouton est appuyé ou pas.
La subtilité c'est que la fonction appelé en callback prend en paramètre un char qui est le "nom" de la touche. Ainsi j'ai ensuite ces lignes de codes :
Code : Tout sélectionner
DcsBios::ErgoButton insButtonVAL( "INS_VAL_SW", bouttonPress,'V');
Code : Tout sélectionner
DcsBios::ErgoKnob insKnobVal( "INS_ROT_VAL", rotaryPos);
Le code complet, brute de fonderie ca donne ça, il y a surement des optimisations possible, si y'a un truc qui se comprend pas n'hésitez pas à me poser des questions :
Code : Tout sélectionner
/*
Nicolas DUMAS
--
PCN Poste de Commande Navigation
*/
#define VERSION "0.2b"
#define AUTHOR "Ergo"
#define DCSBIOS_IRQ_SERIAL
// include the library code:
#include <LiquidCrystal.h>
#include <DcsBios.h>
// -----------------------------------------
// Le LCD :
// -----------------------------------------
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
#define LCD_LEDPWR 6
// -----------------------------------------
// -----------------------------------------
// Registre pour les LEDS :
// -----------------------------------------
#define LED_LUMI 3
#define LED_SDIN 46
#define LED_RCLK 48
#define LED_SRCLK 50
#define LED_SRCLR 52
// registre qui permet d'allumer les leds ou non
int registers[8] = {LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW} ;
// -----------------------------------------
// -----------------------------------------
// le clavier :
// -----------------------------------------
#define KEY_PREP 45
#define KEY_VAL 35
#define KEY_ROW1 43
#define KEY_ROW2 41
#define KEY_ROW3 39
#define KEY_ROW4 37
#define KEY_COL1 25
#define KEY_COL2 27
#define KEY_COL3 29
#define KEY_COL4 31
char KEY_Map[][4] = {"D123", // D 1 2 3
"B456", // B 4 5 6
"M789", // R 7 8 9
"RE0I"} ; // M E 0 I
// -----------------------------------------
// -----------------------------------------
// le rotary :
// -----------------------------------------
// les numéros sont dans l'ordre de la position TR/VS
// et incremetalement dans le sens des aiguilles d'une montre :
int ROT_index[12] = { 30, 32, 34, 36, 38, 40, 42, 23, 22, 24, 26, 28} ;
int ROT_cur = 0;
int ROT_lst = 0;
// -----------------------------------------
// -----------------------------------------
// variable global pour les traitements :
// -----------------------------------------
String LCD_ligne1("") ; // ce qui va être affiché sur le LCD ligne 1
String LCD_ligne0("") ; // ce qui va être affiché sur le LCD ligne 0
bool LCD_cleared = false ; // demande d'effacement du LCD
bool LCD_render = true;
char KEY_cur = ' ' ; // touche pressé courante
char KEY_lst = ' ' ; // touche pressé precedante
int LCD_lumi = 160 ; // luminosité appliqué au système
int LED_lumi = 120 ; // luminosité appliqué au système
// -----------------------------------------
// -----------------------------------------
// Variable pour le "mini OS" :
// -----------------------------------------
#define DEBUG false
unsigned long SYS_precTime = 0;
void(* SYS_reset) (void) = 0;
bool SYS_startup = true ;
#define CC_time 50
// -----------------------------------------
// Variable pour ecrire à l'ecran
// -----------------------------------------
char* TOP_LEFT;
char* TOP_RIGHT;
// -----------------------------------------
#if DEBUG == true
void debug(String txt)
{
Serial.print(String("DEBUG : "+ txt + "\n"));
}
void error(String txt)
{
Serial.print(String("ERROR : "+ txt + "\n"));
}
#else
void debug(String txt) {;}
void error(String txt) {;}
#endif
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("init ...");
pinMode(LCD_LEDPWR, OUTPUT) ;
analogWrite(LCD_LEDPWR,LCD_lumi);
//keyboard
pinMode(KEY_COL1, OUTPUT);
pinMode(KEY_COL2, OUTPUT);
pinMode(KEY_COL3, OUTPUT);
pinMode(KEY_COL4, OUTPUT);
pinMode(KEY_ROW1, INPUT_PULLUP);
pinMode(KEY_ROW2, INPUT_PULLUP);
pinMode(KEY_ROW3, INPUT_PULLUP);
pinMode(KEY_ROW4, INPUT_PULLUP);
pinMode(KEY_PREP, INPUT_PULLUP);
pinMode(KEY_VAL , INPUT_PULLUP);
//led shifter
pinMode(LED_LUMI, OUTPUT); // pwn enable
pinMode(LED_SDIN, OUTPUT); // Serial data input SER_Pin
pinMode(LED_RCLK, OUTPUT); // Storage register RCLK_Pin
pinMode(LED_SRCLK, OUTPUT); // Shift register SRCLK_Pin
pinMode(LED_SRCLR, OUTPUT); // Master reclear SRCLR_Pin
//le rotary :
for(int i=0; i<12; i++)
{
pinMode(ROT_index[i] , INPUT_PULLUP);
}
analogWrite(LED_LUMI,255-LED_lumi);
digitalWrite(LED_SRCLR, HIGH); // master reclear desactive = HIGH
DcsBios::setup();
//Serial.begin(9600);
//while (!Serial) { }
}
void loop()
{
unsigned long SYS_currentTime ;
SYS_currentTime = millis() ;
if (SYS_currentTime - SYS_precTime >= CC_time)
{
SYS_precTime = SYS_currentTime ;
if (SYS_startup)
{
SYS_start();
}
else
{
SYS_main() ;
}
}
if (millis() - SYS_currentTime >CC_time)
{
error(String("overtime (01) : ")+ (millis() - SYS_currentTime) + "ms");
}
}
// =============================================
// fonction appelé tant que SYS_startup = true
// =============================================
void SYS_start()
{
lireEntree() ;
//truc à la con pour faire joli :
static bool startup = false ;
static int step_start = 0 ;
if (! startup)
{
step_start++ ;
switch (step_start)
{
case 1 :
setRegisterPin(6,HIGH) ;
break ;
case 3 :
setRegisterPin(5,HIGH) ;
break ;
case 5 :
setRegisterPin(4,HIGH) ;
break ;
case 7 :
setRegisterPin(3,HIGH) ;
break ;
case 9 :
setRegisterPin(2,HIGH) ;
break ;
case 11 :
LCD_ligne0 = String("Ready ");
setRegisterPin(2,HIGH) ;
break ;
case 16 :
LCD_cleared = true ;
clearRegisters();
startup = true;
invertRegisters();
break ;
}
ecrireSortie();
return ;
}
//-- fin du truc à la con
LCD_ligne0 = String(" >>> PCN <<< ");
static int page_cur = 0 ;
static int page_lst = 0 ;
page_lst = page_cur ;
if (isPress('I')) page_cur ++ ;
if (isPress('E')) SYS_reset() ;
if (page_cur != page_lst) LCD_cleared = true ;
switch (page_cur)
{
case 0 :
LCD_ligne1 = String(" v") + VERSION + " by " + AUTHOR + " ";
break;
case 1 :
// reglage de la luminosité :
if (isPress('1')) LCD_lumi += 25 ;
if (isPress('3')) LCD_lumi += 25 ;
if (isPress('7')) LCD_lumi -= 25 ;
if (isPress('9')) LCD_lumi -= 25 ;
if (LCD_lumi > 255) LCD_lumi = 255 ;
if (LCD_lumi < 0) LCD_lumi = 0 ;
LCD_ligne1 = String("Lumi LCD : ") + String(LCD_lumi) + " ";
break;
case 2 :
// reglage de la luminosité :
setRegisters() ;
if (isPress('1')) LED_lumi += 25 ;
if (isPress('3')) LED_lumi += 25 ;
if (isPress('7')) LED_lumi -= 25 ;
if (isPress('9')) LED_lumi -= 25 ;
if (LED_lumi > 255) LED_lumi = 255 ;
if (LED_lumi < 0) LED_lumi = 0 ;
LCD_ligne1 = String("Lumi LED : ") + String(LED_lumi) + " ";
break;
case 3 :
LCD_ligne1 = String("conf saved");
break;
case 4 :
SYS_startup = false ;
clearRegisters();
LCD_cleared = true ;
LCD_render = false ;
break ;
}
ecrireSortie();
}
// =============================================
// fonction pour les traitements
// =============================================
void SYS_main()
{
lireEntree() ;
activerTraitement();
ecrireSortie();
}
void activerTraitement() {
/*
if (KEY_cur != ' '
&& KEY_cur != KEY_lst)
{
switch (KEY_cur)
{
case 'E' :
clearRegisters();
LCD_cleared = true ;
break;
case '1': invertRegisterPin(1); break;
case '2': invertRegisterPin(2); break;
case '3': invertRegisterPin(3); break;
case '4': invertRegisterPin(4); break;
case '5': invertRegisterPin(5); break;
case '6': invertRegisterPin(6); break;
case '7': invertRegisterPin(7); break;
default : break ;
}
LCD_ligne1 += KEY_cur ;
}
*/
DcsBios::loop();
// LCD_ligne0 = TOP_LEFT + " " + TOP_RIGHT ;
}
void lireEntree() {
int row = 0 ;
int col = 0 ;
digitalWrite(KEY_COL1, false);
if (digitalRead(KEY_ROW1) != HIGH) {row = 1 ; col = 1 ; }
if (digitalRead(KEY_ROW2) != HIGH) {row = 2 ; col = 1 ; }
if (digitalRead(KEY_ROW3) != HIGH) {row = 3 ; col = 1 ; }
if (digitalRead(KEY_ROW3) != HIGH) {row = 4 ; col = 1 ; }
digitalWrite(KEY_COL1, true);
digitalWrite(KEY_COL2, false);
if (digitalRead(KEY_ROW1) != HIGH) {row = 1 ; col = 2 ; }
if (digitalRead(KEY_ROW2) != HIGH) {row = 2 ; col = 2 ; }
if (digitalRead(KEY_ROW3) != HIGH) {row = 3 ; col = 2 ; }
if (digitalRead(KEY_ROW4) != HIGH) {row = 4 ; col = 2 ; }
digitalWrite(KEY_COL2, true);
digitalWrite(KEY_COL3, false);
if (digitalRead(KEY_ROW1) != HIGH) {row = 1 ; col = 3 ; }
if (digitalRead(KEY_ROW2) != HIGH) {row = 2 ; col = 3 ; }
if (digitalRead(KEY_ROW3) != HIGH) {row = 3 ; col = 3 ; }
if (digitalRead(KEY_ROW4) != HIGH) {row = 4 ; col = 3 ; }
digitalWrite(KEY_COL3, true);
digitalWrite(KEY_COL4, false);
if (digitalRead(KEY_ROW1) != HIGH) {row = 1 ; col = 4 ; }
if (digitalRead(KEY_ROW2) != HIGH) {row = 2 ; col = 4 ; }
if (digitalRead(KEY_ROW3) != HIGH) {row = 3 ; col = 4 ; }
if (digitalRead(KEY_ROW4) != HIGH) {row = 4 ; col = 4 ; }
digitalWrite(KEY_COL4, true);
KEY_lst = KEY_cur ;
if (row != 0 && col !=0)
{
KEY_cur = KEY_Map[row-1][col-1] ;
debug(String("touch : ") + row + ":" + col + " : " + KEY_Map[row-1][col-1]) ;
}
else
{
KEY_cur = ' ' ;
}
if (digitalRead(KEY_VAL) != HIGH) KEY_cur = 'V';
if (digitalRead(KEY_PREP) != HIGH) KEY_cur = 'P' ;
// lecture du rotary :
ROT_lst = ROT_cur ;
for(int i=0; i<12; i++)
{
if (digitalRead(ROT_index[i]) != HIGH)
{
ROT_cur = i ;
}
}
}
void ecrireSortie() {
//-------
//gestion du LCD :
//-------
if (LCD_cleared)
{
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
LCD_ligne0 = String();
LCD_ligne1 = String();
LCD_cleared = false ;
}
else if (LCD_render)
{
lcd.setCursor(0, 0);
lcd.print(LCD_ligne0) ;
lcd.setCursor(0, 1);
lcd.print(LCD_ligne1) ;
}
//-------
//-------
// gestion de la luminosité :
//-------
analogWrite(LCD_LEDPWR,LCD_lumi);
analogWrite(LED_LUMI,255-LED_lumi);
//-------
//-------
// gestion des leds :
//-------
digitalWrite(LED_RCLK, LOW);
for(int i = 7; i >= 0; i--)
{
digitalWrite(LED_SRCLK, LOW);
int val = registers[i];
digitalWrite(LED_SDIN, val);
digitalWrite(LED_SRCLK, HIGH);
}
digitalWrite(LED_RCLK, HIGH);
//-------
}
//==============================================================================
// fonctions annexes (libraries interne)
//==============================================================================
bool isPress(char c)
{
return (KEY_cur != KEY_lst) && (KEY_cur == c) ;
}
void invertRegisters()
{
for(int i = 7; i >= 0; i--)
{
invertRegisterPin(i);
}
}
void clearRegisters()
{
for(int i = 7; i >= 0; i--)
{
registers[i] = LOW;
}
}
void setRegisters()
{
for(int i = 7; i >= 0; i--)
{
registers[i] = HIGH;
}
}
void setRegisterPin(int index, int value)
{
registers[index] = value;
}
void invertRegisterPin(int index)
{
if (registers[index] == LOW)
{
registers[index] = HIGH ;
}
else
{
registers[index] = LOW ;
}
}
String substr(String s, int start) {
if (start > 0)
return s.substring(start);
return s.substring(s.length() + start) ;
}
/*** DCS BIOS part ***/
namespace DcsBios {
class ErgoButton : PollingInput {
private:
const char* msg_;
bool (*callback_)(char)=0 ;
bool lastState_;
char key_;
void init_(const char* msg, bool (*callback)(char), char key) {
msg_ = msg;
callback_ = callback;
lastState_ = false;
key_ = key;
}
void pollInput() {
bool state = callback_(key_);
if (state != lastState_) {
if (tryToSendDcsBiosMessage(msg_, state == true ? "0" : "1")) {
lastState_ = state;
}
}
}
public:
ErgoButton(const char* msg, bool (*callback)(char),char key)
{
init_(msg, callback,key);
}
};
class ErgoKnob : PollingInput {
private:
const char* msg_;
int (*callback_)()=0 ;
int lastPos_;
void init_(const char* msg, int (*callback)()) {
msg_ = msg;
callback_ = callback;
lastPos_ = callback();
}
void pollInput()
{
int pos = callback_();
if (pos != lastPos_)
{
byte buff[] = " " ;
String(pos).getBytes(buff,3);
if (tryToSendDcsBiosMessage(msg_, buff) )
{
lastPos_ = pos;
}
}
}
public:
ErgoKnob(const char* msg, int (*callback)())
{
init_(msg, callback);
}
};
}
// VOYANT UNI (rouge)
void onPcnUniChange(unsigned int newValue) {
setRegisterPin(1, (newValue == 0 ? LOW : HIGH)) ;
}
DcsBios::IntegerBuffer pcnUniBuffer(0x3082, 0x1000, 12, onPcnUniChange);
// VOYANT PRET (vert)
void onPcnPretChange(unsigned int newValue) {
setRegisterPin(2, (newValue == 0 ? LOW : HIGH)) ;
}
DcsBios::IntegerBuffer pcnPretBuffer(0x3082, 0x0080, 7, onPcnPretChange);
// VOYANT ALN (jaune)
void onPcnAlnChange(unsigned int newValue) {
setRegisterPin(3, (newValue == 0 ? LOW : HIGH)) ;
}
DcsBios::IntegerBuffer pcnAlnBuffer(0x3082, 0x0100, 8, onPcnAlnChange);
// VOYANT MIP
void onPcnMipChange(unsigned int newValue) {
setRegisterPin(4, (newValue == 0 ? LOW : HIGH)) ;
}
DcsBios::IntegerBuffer pcnMipBuffer(0x3082, 0x0200, 9, onPcnMipChange);
// VOYANT NDEG
void onPcnNdegChange(unsigned int newValue) {
setRegisterPin(5, (newValue == 0 ? LOW : HIGH)) ;
}
DcsBios::IntegerBuffer pcnNdegBuffer(0x3082, 0x0400, 10, onPcnNdegChange);
// VOYANT SEC
void onPcnSecChange(unsigned int newValue) {
setRegisterPin(6, (newValue == 0 ? LOW : HIGH)) ;
}
DcsBios::IntegerBuffer pcnSecBuffer(0x3082, 0x0800, 11, onPcnSecChange);
//BOUTONS
bool bouttonPress(char c)
{
return isPress(c);
}
DcsBios::ErgoButton insButtonVAL( "INS_VAL_SW", bouttonPress,'V');
DcsBios::ErgoButton insButtonPREP("INS_PREP_SW", bouttonPress,'P');
DcsBios::ErgoButton insButtonDEST("INS_DEST_SW", bouttonPress,'D');
DcsBios::ErgoButton insButtonINS( "INS_BUTTON_INS", bouttonPress,'I');
DcsBios::ErgoButton insButtonEFF( "INS_BUTTON_EFF", bouttonPress,'E');
DcsBios::ErgoButton insButton1( "INS_BUTTON_1", bouttonPress,'1');
DcsBios::ErgoButton insButton2( "INS_BUTTON_2", bouttonPress,'2');
DcsBios::ErgoButton insButton3( "INS_BUTTON_3", bouttonPress,'3');
DcsBios::ErgoButton insButton4( "INS_BUTTON_4", bouttonPress,'4');
DcsBios::ErgoButton insButton5( "INS_BUTTON_5", bouttonPress,'5');
DcsBios::ErgoButton insButton6( "INS_BUTTON_6", bouttonPress,'6');
DcsBios::ErgoButton insButton7( "INS_BUTTON_7", bouttonPress,'7');
DcsBios::ErgoButton insButton8( "INS_BUTTON_8", bouttonPress,'8');
DcsBios::ErgoButton insButton9( "INS_BUTTON_9", bouttonPress,'9');
DcsBios::ErgoButton insButton0( "INS_BUTTON_0", bouttonPress,'0');
//KNOBS
int rotaryPos()
{
return ROT_cur;
}
DcsBios::ErgoKnob insKnobVal( "INS_ROT_VAL", rotaryPos);
void onPcnDispLChange(char* newValue) {
//TOP_LEFT = newValue;
lcd.setCursor(1, 0);
lcd.print(newValue);
}
DcsBios::StringBuffer<8> pcnDispLBuffer(0x3084, onPcnDispLChange);
void onPcnDispRChange(char* newValue) {
//TOP_RIGHT = newValue;
lcd.setCursor(7, 1);
lcd.print(newValue);
}
DcsBios::StringBuffer<9> pcnDispRBuffer(0x308c, onPcnDispRChange);
void onPcnDispDChange(char* newValue) {
lcd.setCursor(3, 1);
lcd.print(newValue);
}
DcsBios::StringBuffer<2> pcnDispDBuffer(0x3096, onPcnDispDChange);
void onPcnDispPChange(char* newValue) {
lcd.setCursor(0, 1);
lcd.print(newValue);
}
DcsBios::StringBuffer<2> pcnDispPBuffer(0x3098, onPcnDispPChange);
void onPcnDisDlChange(char* newValue) {
lcd.setCursor(0, 0);
lcd.print(newValue);
}
DcsBios::StringBuffer<1> pcnDisDlBuffer(0x309a, onPcnDisDlChange);
void onPcnDisDrChange(char* newValue) {
lcd.setCursor(6, 1);
lcd.print(newValue);
}
DcsBios::StringBuffer<1> pcnDisDrBuffer(0x309c, onPcnDisDrChange);