#include <lcdgfx.h> //lcd(模組) 螢幕大小128*158
#include <SPI.h> //spi協定(mosi走pin17 sck走19 ss走6?)
#define cs 4 //必須確保是輸出而非輸入(多數函式庫有用了可不以不在意) 否則會被當成僕機
#define dc 5
#define rst 3 //把lcd清空成預設
//MISO (gpio12)固定但大多不用 lcd幾乎都半單向寫 所以都留空
//跟TFT等畫圖一樣左上角為原點 y軸往下
//-------- 按鍵 元件接腳名稱控制參數設定 ----------------------------------------
#define BTN_1 14 //第一顆按鈕定義權重為 1 接至 PC1, GPIO_14 需設為INPUT 模式
#define BTN_2 15 //第一顆按鈕定義權重為 2 接至 PC2, GPIO_15 需設為INPUT 模式
#define BTN_3 16 //第一顆按鈕定義權重為 3 接至 PC3, GPIO_16 需設為INPUT 模式
#define BTN_4 17//第一顆按鈕定義權重為 4 接至 PC4, GPIO_17 需設為INPUT 模式
char pinINPUT[]={BTN_1,BTN_2,BTN_3,BTN_4};
DisplayST7735_128x160x16_SPI TFT(
rst,
{ -1, cs, dc, 0, -1, -1 }); //建立一個lcd物件 指定接腳(沒用的-1 0gpio0 ) {rst,(sck,cs,dc,mosi,miso,other) }
void setup() {
Serial.begin(115200);Serial.setTimeout(5);// 設定串列式通訊協定的傳輸率為115200及 5ms讀一個讀資料的週期
for (int i=0; i<(sizeof(pinINPUT)/sizeof(char)); i++) pinMode(pinINPUT[i], INPUT);
TFT.begin();
TFT.clear();
TFT.getInterface().setRotation(2); // 旋轉方向(0‧1‧2‧3,分別轉0~270度)
TFT.setFixedFont(ssd1306xled_font6x8); // 指定字型
TFTshow();
}
//------------------
int menu=0;//0選功能 1連線(目前沒) 2rgb 3計數 4密碼
int modec =0;//menu0會有4個(0連線(目前沒) 1rgb 2計數 3密碼) 2會有3(3個模式) 3會有2(2個模式)
const char *menu0[] = {"Connect to BLE","RGB offline ","CountDown ","EEPROM "};// 常數放 Flash,使用時不載入 SRAM
const char *menu2[] = {"1.RED(3LEDs)","2.Green(6LEDs)","3.Blue(8LEDs)","4.Gragient RGB"};
const char status[] = "connect to ble";
bool status2=0;
bool block=1;
void choose(int ram0,int ram,const char* const * ram1){//從哪開始印,要印幾個(-1),要印的內容(陣列) 列印選單 最外層指標不可變 (const*)指向的字串也不可改 (char* const)這樣函式保證不會錯把資料改掉。
for (int i = 0,j=ram0; i <= ram; i++,j +=12){
if(modec==i){//被選到
TFT.setColor(RGB_COLOR16(0, 0, 0)); //前景色
TFT.setBackground(RGB_COLOR16(255,255, 255));//後景色
}
else{//沒被選到
TFT.setColor(RGB_COLOR16(255, 255, 255));
TFT.setBackground(RGB_COLOR16(0,0, 0));
}
TFT.printFixed(10, j,ram1[i] , STYLE_BOLD); //只吃char不吃string
}
}
int TFTshow(){//TFT
if (block){TFT.drawWindow(0, 0, 0, 0, "", true);block = 0;}//因為每次執行到畫框都會把畫面洗掉(clear)(即使只畫在原本的地方)所以放這只執行一次 有bug menu4進去出來都沒框
TFT.setColor(RGB_COLOR16(255,255, 255));
TFT.setBackground(RGB_COLOR16(0,0, 0));
if (menu == 0){
TFT.printFixedN(40, 10, "MENU", STYLE_NORMAL,1);//列印字串 起始xy,字串,輸出方式(NORMAL是正常透明)**BOLD粗體 ITALIC斜體
choose(30,3,menu0);
}
else if (menu==1){
TFT.setColor(RGB_COLOR16(0, 0, 0));
TFT.setBackground(RGB_COLOR16(255,255, 255));
TFT.printFixed(10, 20,status, STYLE_BOLD); //只吃char不吃string
TFT.setColor(RGB_COLOR16(255, 255, 255));
TFT.setBackground(RGB_COLOR16(0,0, 0));
TFT.printFixed(10, 40,status2?"isconnect ":"notconnect" , STYLE_BOLD); //只吃char不吃string
}
else if (menu==2){
TFT.printFixed(31, 10, "RGB offline ", STYLE_NORMAL);//列印字串 起始xy,字串,輸出方式(NORMAL是正常透明)**BOLD粗體 ITALIC斜體
choose(30,3,menu2);
}
else if (menu==3){
TFT.printFixed(10, 10,"" , STYLE_BOLD); //只吃char不吃string
TFT.print(10); //專門打印整數數字的
}
else if (menu==4){
TFT.printFixed(10, 10,"eeprom", STYLE_BOLD); //只吃char不吃string
}
}
//------------按鍵讀取資料副程式----------------------------
int nowkey;
int oldkey = -1;
unsigned long int preMillisled;
int ReadKey(void){
int key=0;
if( digitalRead(BTN_1)==0 )key = 1;//當PUSH_B1按下時為低電位,ReadKey()副程式傳回數值1
if( digitalRead(BTN_2)==0 )key = 2;//當PUSH_B2按下時為低電位,ReadKey()副程式傳回數值2
if( digitalRead(BTN_3)==0 )key = 3; //當PUSH_B3按下時為低電位,ReadKey()副程式傳回數值3
if( digitalRead(BTN_4)==0 )key = 4; //當PUSH_B4按下時為低電位,ReadKey()副程式傳回數值4
return key;
}
void switchkey(){
nowkey=ReadKey();
if (nowkey == oldkey){return;}
unsigned long ram = millis()-preMillisled;
if (ram >= 10){
oldkey = nowkey;
preMillisled = millis();
switch(nowkey){
case 1:if (menu != 0){modec=menu-1;menu=0;TFT.clear();block = 1;}break;//退
case 2://進
if (menu==0){
switch(modec){
case 0:menu=1;modec=0;break;
case 1:menu=2;modec=0;break;
case 2:menu=3;break;
default:menu=4;break;
}
TFT.clear();
block = 1;
}
else if (menu ==1){
status2 = !status2;
}
break;
case 3:
if (menu==0){modec=(modec+7)%4;}
if (menu==2){modec=(modec+7)%4;}
break;//上
case 4:
if (menu==0){modec=(modec+1)%4;}
if (menu==2){modec=(modec+1)%4;}
break;//下
default:break;
}
TFTshow();
}
}
void loop() {
switchkey();
}
/*
//----------tft測試
int tfttest(){
TFT.fill(RGB_COLOR16(0, 0, 0));//設定背景色
TFT.getInterface().setRotation(2); // 旋轉方向(0‧1‧2‧3,分別轉0~270度)
TFT.setFixedFont(ssd1306xled_font6x8); // 指定字型
// ssd1306xled_font6x8 ─ 6×8 ASCII
// ssd1306xled_font6x8_F ─ 6×8 ASCII和一些變形字
// ssd1306xled_font8x16 ─ 8×16 ASCII
// free_monospaced_10px / 12px ─ 7×10、8×12 ASCII
// unisteg_14px ─ 9×14 ASCII + 一些中文字跟符號
TFT.setColor(RGB_COLOR16(255, 255, 255)); // 設定畫筆顏色(前景色)
TFT.fillRect(100,0,150,20); // 劃一個矩形(左上和右下的座標)
TFT.setColor(RGB_COLOR16(255, 255, 0));
TFT.setBackground(RGB_COLOR16(255, 0, 0));//設定後景色 預設黑色
TFT.printFixed(20, 20, "Hello ", STYLE_BOLD);//列印字串 起始xy,字串,輸出方式(NORMAL是正常透明)**BOLD粗體 ITALIC斜體
TFT.setBackground(RGB_COLOR16(0, 0, 0));//設定後景色 預設黑色
TFT.printFixedN(20, 40, "Hello x2", STYLE_ITALIC, 1);//這個可以設定字的大小 (用2為底數的次方 1就2的1次方)
TFT.setColor(RGB_COLOR16(255, 0, 0));
TFT.drawCircle(50, 80, 20); // 半徑15 的空心圓
TFT.drawWindow(10, 100, 100, 80, "Downloading", true);//劃一個帶標題的框(xy,外框大小的寬高(0預設整個螢幕),文字,裡面中空)
}*/