Apologise for lot of italian comments
//PROGRAMMA PER TASTIERA BT PER OSMAND
//LA TASTIERA è LA ACUMA P5-BT CHE HA LA SEGUENTE SPECIFICA:
//LA TASTIERA è COMPOSTA DA 4 TASTI E DA UN MINIJOYSTICK PER FARE IL PAN E CON UNO SWITCH INTERNO SE VIENE PREMUTO IL JOYSTICK
//LA SOMMA TOTALE QUINDI DELLE FUNZIONI è DI 9 (4 TASTI, 4 DIREZIONI JOYSTICK, 1 SWITCH JOYSTICK), ECCO PERCHè QUINDI LA FUNZIONE KEYBOARD è IDEALE
//LA TASTIERA DEVE POTER CONTROLLARE OSMAND E LE ALTRE APP PER NAVIGARE CON IL ROADBOOK ELETTRONICO
//QUINDI SI RENDONO NECESSARIE 2 KEYMAP CHE DOVRANNO ESSERE SELEZIONATE TRAMITE LA PRESSIONE LUNGA DI UN TASTO:
//KEYMAP 0 --> OSMAND
//KEYMAP 1 --> ROADBOOK
//KEYMAP 0 - TABELLA CIFRAvsCARATTEREvsFUNZIONE:
//SHORT PRESS / CLICK
//1 --> VOL+ --> ZOOM+
//2 --> ARROW UP --> PAN UP
//3 --> D --> CHANGE MAP ORIENTATION
//4 --> ARROW LEFT --> PAN LEFT
//5 --> C --> CENTER POSITION
//6 --> ARROW RIGHT --> PAN RIGHT
//7 --> VOL- --> ZOOM-
//8 --> ARROW DOWN --> PAN DOWN
//9 --> NULL/NIENTE
//LONG PRESS / HOLD
//1 --> VOL+ --> ZOOM+
//2 --> ARROW UP --> PAN UP
//3 --> D --> CHANGE MAP ORIENTATION
//4 --> ARROW LEFT --> PAN LEFT
//5 --> C --> CAMBIO MAPPA
//6 --> ARROW RIGHT --> PAN RIGHT
//7 --> VOL- --> ZOOM-
//8 --> ARROW DOWN --> PAN DOWN
//9 --> NULL/NIENTE
//KEYMAP 1 - TABELLA CIFRAvsCARATTEREvsFUNZIONE:
//SHORT PRESS / CLICK
//1 --> ARROW UP --> SCROLL UP
//2 --> ARROW UP --> SCROLL UP
//3 --> VOL+ --> TRIP +
//4 --> ARROW LEFT --> NULL
//5 --> C --> NULL
//6 --> ARROW RIGHT --> NULL
//7 --> ARROW DOWN --> SCROLL DOWN
//8 --> ARROW DOWN --> SCROLL DOWN
//9 --> VOL- --> TRIP-
//LONG PRESS / HOLD
//1 --> ARROW UP --> SCROLL UP
//2 --> ARROW UP --> SCROLL UP
//3 --> VOL+ --> TRIP +
//4 --> ARROW LEFT --> NULL
//5 --> C --> CAMBIO MAPPA
//6 --> ARROW RIGHT --> NULL
//7 --> ARROW DOWN --> SCROLL DOWN
//8 --> ARROW DOWN --> SCROLL DOWN
//9 --> VOL- --> TRIP-
//si utilizza la libreria keypad per gestire in maniera efficace l'impiego di una tastiera semplice (in questo caso una 3x3)
//si utilizza la libreria BleKeyboard che serve per mandare i comandi corretti a osmand
//tasti direzionali --> pan
//vol +- --> zoom
//c--> ricentra la mappa
//d --> cambia orientamento
//serve poi fare la comunicazione BT tramite una libreria apposita
//i tasti direzionali vengono comandati da un joystick che a sua volta pilota dei transistor
//NB, non si fa uso di transistor, e a causa dello schema del joystick, siamo costretti a usare una tastiera 2x5 di cui però non verrà usato il carattere A
//PER INCLUDERE LA LIBREREIA BLE SI DEVE SCRIVERE COSI
#include <BleKeyboard.h>
BleKeyboard bleKeyboard("ACUMA_P5_01", "ACUMA", 100);
//INCLUSIONE LIBRERIA KEYPAD
#include <Keypad.h>
//GESTIONE LED RGB DI STATO
/******************** definizione delle costanti **********************************/
int portarossa = D7; // porta 11 da collegare all’anodo “rosso” del modulo RGB
int portaverde = D8; // porta 10 da collegare all’anodo “verde” del modulo RGB
int portablu = D9; // porta 9 da collegare all’anodo “blu” del modulo RBG
/**********************routine di accensione del led ********************************
nelle prossime righe viene definita la routine “colore” che, al momento del lancio, e’
accompagnata da tre variabili (rosso, verde e blu) che contengono i valori dell’intensita’
luminosa, di volta in volta voluta, per ogni singolo led (0 = minim0a e 255 = massima) */
void colore (unsigned char rosso, unsigned char verde, unsigned char blu)
{
analogWrite(portarossa, rosso); //attiva il led rosso con l’intensita’ definita nella variabile rosso
analogWrite(portablu, blu); //attiva il led blu con l’intensita’ definita nella variabile blu
analogWrite(portaverde, verde); //attiva il led verde con l’intensita’ definita nella variabile verde
}
//dichiaro il numero di righe e colonne della tastiera
const int nR = 2;
const int nC = 5;
//mappa dei caratteri che ci serviranno come riferimento per usare il costrutto "case"
const char acumaMap[nR][nC] =
{
{ '2', '8', '4', '6', '5'},
{ '1', '7', '3', '9', 'A'}
};
//definizione dei pin connessi alla keypad, devi usare byte perchè altrimenti non funziona
byte rowPin[nR] = {D0, D1};
byte colPin[nC] = {D2, D3, D4, D5, D6};
//costruzione della tastiera, la sintassi è questa. dove acumaP5 è il nome della tastiera e viene usata la mappa dei tasti
Keypad acumaP5 = Keypad( makeKeymap(acumaMap), rowPin, colPin, nR, nC );
unsigned long hold_time = millis();
// define time for a long press (ms)
const int long_press_time = 440;
const int long_press_repeat_interval = 160;
// Variable that holds the current active keymap
int current_keymap = 0;
// How many keymaps do we have?
const int KEYMAP_COUNT = 2;
void send_short_press(KeypadEvent key) {
switch (key) {
case '1':
switch (current_keymap) {
case 0: bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
break;
case 1: bleKeyboard.write(KEY_MEDIA_PREVIOUS_TRACK);
break;
}
break;
case '2':
switch (current_keymap) {
case 0: bleKeyboard.write(KEY_UP_ARROW);
break;
case 1: bleKeyboard.write(KEY_MEDIA_PREVIOUS_TRACK);
break;
}
break;
case '3':
switch (current_keymap) {
case 0: bleKeyboard.write('d');
break;
case 1: bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
break;
}
break;
case '4':
switch (current_keymap) {
case 0: bleKeyboard.write(KEY_LEFT_ARROW);
break;
case 1: bleKeyboard.write(KEY_LEFT_ARROW);
break;
}
break;
case '5':
switch (current_keymap) {
case 0: bleKeyboard.write('c');
break;
case 1: bleKeyboard.write('c');
break;
}
break;
case '6':
switch (current_keymap) {
case 0: bleKeyboard.write(KEY_RIGHT_ARROW);
break;
case 1: bleKeyboard.write(KEY_RIGHT_ARROW);
break;
}
break;
case '7':
switch (current_keymap) {
case 0: bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
break;
case 1: bleKeyboard.write(KEY_MEDIA_NEXT_TRACK);
break;
}
break;
case '8':
switch (current_keymap) {
case 0: bleKeyboard.write(KEY_DOWN_ARROW);
break;
case 1: bleKeyboard.write(KEY_MEDIA_NEXT_TRACK);
break;
}
break;
case '9':
switch (current_keymap) {
case 1: bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
break;
}
break;
}
}
void send_long_press(KeypadEvent key) {
Serial.println(key);
switch (key) {
case '1':
switch (current_keymap) {
case 0: send_repeating_key(KEY_MEDIA_VOLUME_UP);
break;
case 1: send_repeating_key(KEY_MEDIA_PREVIOUS_TRACK);
break;
}
break;
case '2':
switch (current_keymap) {
case 0: send_repeating_key(KEY_UP_ARROW);
break;
case 1: send_repeating_key(KEY_MEDIA_PREVIOUS_TRACK);
break;
}
break;
case '3':
switch (current_keymap) {
case 0: bleKeyboard.write('d');
break;
case 1: send_repeating_key(KEY_MEDIA_VOLUME_UP);
break;
}
break;
case '4':
switch (current_keymap) {
case 0: send_repeating_key(KEY_LEFT_ARROW);
break;
case 1: send_repeating_key(KEY_LEFT_ARROW);
break;
}
break;
case '5': switch_keymap();
break;
case '6':
switch (current_keymap) {
case 0: send_repeating_key(KEY_RIGHT_ARROW);
break;
case 1: send_repeating_key(KEY_RIGHT_ARROW);
break;
}
break;
case '7':
switch (current_keymap) {
case 0: send_repeating_key(KEY_MEDIA_VOLUME_DOWN);
break;
case 1: send_repeating_key(KEY_MEDIA_NEXT_TRACK);
break;
}
break;
case '8':
switch (current_keymap) {
case 0: send_repeating_key(KEY_DOWN_ARROW);
break;
case 1: send_repeating_key(KEY_MEDIA_NEXT_TRACK);
break;
}
break;
case '9':
switch (current_keymap) {
case 1: send_repeating_key(KEY_MEDIA_VOLUME_DOWN);
break;
}
break;
}
}
void send_repeating_key(uint8_t key) {
while (acumaP5.getState() == HOLD) {
bleKeyboard.write(key);
delay(long_press_repeat_interval);
acumaP5.getKey();
}
}
void send_repeating_key(const MediaKeyReport key) {
while (acumaP5.getState() == HOLD) {
bleKeyboard.write(key);
delay(long_press_repeat_interval);
acumaP5.getKey();
}
}
void keypad_handler(KeypadEvent key) {
switch (acumaP5.getState()) {
case PRESSED:
send_short_press(key);
break;
case HOLD:
send_long_press(key);
break;
}
}
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
// pinMode (12, OUTPUT);
Serial.begin (9600);
bleKeyboard.begin();
acumaP5.addEventListener(keypad_handler); // Add an event listener for this keypad
acumaP5.setHoldTime(long_press_time);
pinMode(portarossa, OUTPUT); // dichiara la porta 11 come porta di output
pinMode(portaverde, OUTPUT); // dichiara la porta 10 come porta di output
pinMode(portablu, OUTPUT); // dichiara la porta 9 come porta di output
}
// the loop function runs over and over again forever
void loop() {
acumaP5.getKey(); //key è la variabile a cui viene assegnato il numero della tastiera con l'istruzione getkey
//delay(10);
char key = acumaP5.getKey();
Serial.println(key); //se voglio stamparla sul serial monitor
//Serial.println(acumaP5.getState());
//gestione colori mappe
if (bleKeyboard.isConnected()) {
switch (current_keymap) {
case 0: colore(0, 0, 255);
break;
case 1: colore(0, 255, 0);
break;
}
}
else {
colore(255, 0, 0);
}
}
// This function cycles the keymap and signals the new keymap via the LED
void switch_keymap() {
// Serial.println("Switching keymap");
// cycle to next keymap
current_keymap++;
if (current_keymap > KEYMAP_COUNT - 1) {
current_keymap = 0;
}
}