/
k3dr
/
stationProgrammer
Обзор
Документация
Войти
/
k3dr
/
stationProgrammer
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Programmer/Programmer.ino
358 строк
9 KB
k3dr
upload files
11 янв 2026, 10:23
11 янв 2026, 10:23
ccd2d23
Код
Авторство
О чём код?
#include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 32 #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define Apin 18 #define Bpin 4 #define BTNpin 19 //pages codes for page processor #define MENU -1 //States of connection process #define CONNECTED 1 #define UNCONNECTED 2 //Delay between sending and receiving messages #define TRSM_DELAY 300 //Special Struct for receiption and sending data with I2C struct arrowInf { uint8_t pin; // 1 byte uint8_t strPos; // 1 byte uint8_t trnPos; // 1 byte bool curPos; // 1 byte }; const volatile int sizeArrow = sizeof(arrowInf); #define ST_MSG "DEBUG" //1 строчка дисплея - 8 пикселей //используется для сохранения позиции при редактировании значения угла в стрелке int16_t last_position_menu = -1; // -1 - нет никакой позиции для сохранения //controlling encoder; int lastAState; int curAState; int lastBtnState; int curBtnSt; int lstBtnSt; int curBState; //page is cursor which shows us a position which page should be drawn int page = MENU; //Cursor orientation int cur_cursor_punct = 0; int changing_ang_mode = 0; //global var for arrow settings; int cur_ch_angle; //Flag of state of connection with the station board int connection_state = UNCONNECTED; int arrows_count; //Pin, str_ang, trn_ang, cr_ps arrowInf arrows_inf[20]; void buttonARRProcessor(uint8_t* arr_number, uint8_t* base_str_angle, uint8_t* base_trn_angle, uint8_t* cur_last_position_menu); void buttonMenuProccesor(); void setup() { pinMode(Apin, INPUT_PULLUP); pinMode(Bpin, INPUT_PULLUP); pinMode(BTNpin, INPUT_PULLUP); //Initial state lastAState = digitalRead(Apin); lstBtnSt = digitalRead(BTNpin); attachInterrupt(digitalPinToInterrupt(Apin), update_enc, CHANGE); attachInterrupt(digitalPinToInterrupt(BTNpin), update_btn, CHANGE); Serial.begin(115200); // Wait for display delay(500); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } // the library initializes this with an Adafruit splash screen. display.display(); delay(2000); // Pause for 2 seconds // Clear the buffer display.clearDisplay(); display.display(); // showPrepairingDisplay(); showConnectionDisplay(); } void loop() { if (connection_state==CONNECTED) { displayProcessor(); //Serial.println(page); } else if (connection_state==UNCONNECTED) { startConnectionToStation(); delay(2000); } } //Processing encoder signal changes (encoder inputs) void update_enc() { curAState = digitalRead(Apin); curBState = digitalRead(Bpin); curBtnSt = digitalRead(BTNpin); //Serial.print(curAState); Serial.print(curBState); Serial.println(curBtnSt); if ((curAState != lastAState) && curAState == 1) { if (curBState == curAState) { cur_cursor_punct++; if (changing_ang_mode == 1){ cur_ch_angle++; } } else { cur_cursor_punct--; if (changing_ang_mode == 1) { cur_ch_angle--; } } //Serial.println(cur_cursor_punct); } lastAState = curAState; if (last_position_menu > 25 || last_position_menu < -25) last_position_menu = 0; } //Processing button clicks void update_btn() { curBtnSt = digitalRead(BTNpin); if (curBtnSt != lastBtnState && curBtnSt == 1) { buttonProcessor(); } lastBtnState = curBtnSt; } //Showing information on display void displayProcessor() { display.clearDisplay(); //Drawing menu if (page == MENU) { drawMenu(); } else if (page >= 0 && page < arrows_count) { drawArrTestPage(&arrows_inf[page].pin, &arrows_inf[page].strPos, &arrows_inf[page].trnPos, &arrows_inf[page].curPos); } display.display(); } void buttonProcessor() { if (page == MENU) { buttonMenuProccesor(); } else if (page >= 0 && page < arrows_count) { buttonARRProcessor(&arrows_inf[page].pin, &arrows_inf[page].strPos, &arrows_inf[page].trnPos, &arrows_inf[page].curPos); } } void drawMenu() { display.setCursor(2,0); display.setTextSize(1); display.setTextColor(WHITE); for (int i = 0; i < arrows_count; i++) { display.print("arrow "); display.println(arrows_inf[i].pin); } int x0 = 0, y0; if (cur_cursor_punct > arrows_count-1) { cur_cursor_punct = 0; } else if (cur_cursor_punct <= -1) { cur_cursor_punct = arrows_count-1; } //drink punkt y0 = cur_cursor_punct*8; display.drawRect(x0, y0, 100 , 8, WHITE); } void buttonMenuProccesor() { //Serial.println(page); page = cur_cursor_punct; } void drawArrTestPage(uint8_t* arr_number, uint8_t* base_str_angle, uint8_t* base_trn_angle, bool* cur_last_position_menu) { int y_start = 0; display.clearDisplay(); display.setCursor(0,0); display.setTextColor(WHITE); display.setTextSize(1); display.print("Arrow "); display.print(*arr_number); display.println(" Back ->"); display.drawLine(10,y_start+7,118,y_start+7, WHITE); display.print("STR: "); display.println(*base_str_angle); display.print("TRN: "); display.println(*base_trn_angle); int x0, y0; if (last_position_menu != -1) { cur_cursor_punct = last_position_menu; } else if (cur_cursor_punct <= -1) { cur_cursor_punct = 2; } else if (cur_cursor_punct >= 3){ cur_cursor_punct = 0; } //Back button else if (cur_cursor_punct == 0) { x0 = 70; y0 = 0; display.drawRect(x0, y0, 50, 8, WHITE); } //STR else if (cur_cursor_punct == 1) { x0 = 28; y0 = 8; display.drawRect(x0, y0, 22, 8, WHITE); } //TRN else if (cur_cursor_punct == 2) { x0 = 28; y0 = 16; display.drawRect(x0, y0, 22, 8, WHITE); } } void buttonARRProcessor(uint8_t* arr_number, uint8_t* base_str_angle, uint8_t* base_trn_angle, bool* cur_last_position_menu) { switch (cur_cursor_punct) { case 0: page = MENU; break; case 1: if (changing_ang_mode == 0) { changing_ang_mode = 1; last_position_menu = 1; cur_ch_angle = *base_str_angle; //Serial.println(cur_ch_angle); } else { changing_ang_mode = 0; last_position_menu = -1; //Here we should also add command to send this information to the other board but now here we would have the Serial *base_str_angle = cur_ch_angle; Serial.print("ARR:");Serial.print(*arr_number);Serial.print(';');Serial.print("SET_STR:");Serial.print(cur_ch_angle);Serial.println('.'); } break; case 2: if (changing_ang_mode == 0) { changing_ang_mode = 1; last_position_menu = 2; cur_ch_angle = *base_trn_angle; //Serial.println(cur_ch_angle); } else { changing_ang_mode = 0; last_position_menu = -1; //Here we should also add command to send this information to the other board but now here we would have the Serial *base_trn_angle = cur_ch_angle; Serial.print("ARR:");Serial.print(*arr_number);Serial.print(';');Serial.print("SET_TRN:");Serial.print(cur_ch_angle);Serial.println('.'); } break; } } void showPrepairingDisplay() { display.clearDisplay(); display.setCursor(25,14); display.setTextSize(1); display.setTextColor(WHITE); display.println("Prepairing..."); display.display(); } //Needed to be shown before the connection is setted up void showConnectionDisplay() { display.clearDisplay(); display.setCursor(25,14); display.setTextSize(1); display.setTextColor(WHITE); display.println("Connection..."); display.display(); } void send(const arrowInf* sheet) { Serial.write((const char*)sheet, sizeArrow); } bool receiveArrInf(arrowInf* sheet) { return (Serial.readBytes((char*)sheet, sizeArrow) == sizeArrow); } void startConnectionToStation() { if (!Serial.available() ) { Serial.println(ST_MSG); delay(TRSM_DELAY); arrows_count = (Serial.readStringUntil('\n')).toInt(); for (int i = 0; i < arrows_count; i++) { receiveArrInf(&arrows_inf[i]); delay(TRSM_DELAY); } if (arrows_count) connection_state = CONNECTED; } else { ; } }