diff --git a/Core/Inc/EEPROM.h b/Core/Inc/EEPROM.h index d2fe75c..8dd7c91 100644 --- a/Core/Inc/EEPROM.h +++ b/Core/Inc/EEPROM.h @@ -12,7 +12,7 @@ #define STAT_BLOCKSIZE 128 #define START_ADR_SHOT (START_ADR_STAT+STAT_BLOCKSIZE) -#define SHOT_BLOCKSIZE 10 +#define SHOT_BLOCKSIZE 8 #define MAX_SHOT_COUNT 256 #define START_ADR_PROGRAM (START_ADR_SHOT + (SHOT_BLOCKSIZE*MAX_SHOT_COUNT)) diff --git a/Core/Inc/RobotFunctions.h b/Core/Inc/RobotFunctions.h index 3398c5d..533a7c6 100644 --- a/Core/Inc/RobotFunctions.h +++ b/Core/Inc/RobotFunctions.h @@ -15,6 +15,7 @@ // 1 - setPos IMMEDIATELY #define PRE_RUN_DELAY_MODE 0 #define NOBALL_TIMEOUT_MULTIPLIER 4.2 +#define NOBALL_TIMEOUT_HARD 20000 typedef enum ServoMap{ SERVO_AXIAL = 0, @@ -94,6 +95,7 @@ void setPos(uint8_t axial, uint8_t horizontal, uint8_t vertical); void setPosSingle(ServoMap servo, uint8_t value); void setPosFromShot(Shot* shot); void setPosDefault(); +void setPosOff(); void setPosDefaultSingle(ServoMap servo); // 0 .. 100 diff --git a/Core/Inc/pca9685.h b/Core/Inc/pca9685.h index 11026bf..588ba48 100644 --- a/Core/Inc/pca9685.h +++ b/Core/Inc/pca9685.h @@ -4,4 +4,4 @@ extern I2C_HandleTypeDef hi2c1; void initPCA9685(void); void SetServo(uint8_t channel, uint8_t angel); - +void SetServoOFF(uint8_t channel); diff --git a/Core/Src/EEPROM.c b/Core/Src/EEPROM.c index 5bc6721..ee03225 100644 --- a/Core/Src/EEPROM.c +++ b/Core/Src/EEPROM.c @@ -365,6 +365,7 @@ MemoryStatus FLASH_ReadBlock(uint16_t startAddr, uint8_t number, if ((startAddr == START_ADR_SHOT && number > MAX_SHOT_COUNT) || (startAddr == START_ADR_PROGRAM && number > MAX_PROGRAM_COUNT) || (startAddr == START_ADR_MACRO && number > MAX_MACRO_COUNT)) { + print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11"); return EEPROM_OUT_OF_RANGE; } @@ -379,8 +380,14 @@ MemoryStatus FLASH_ReadBlock(uint16_t startAddr, uint8_t number, HAL_Delay(1); result = HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1) | 1, readData, dataSize, 10); + + print("FLASH_ReadBlock: "); + printNumber(blockAddr16); +// print("\n"); + HAL_Delay(1); if (result != HAL_OK) { + print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11"); return EEPROM_FAIL; } return EEPROM_OK; diff --git a/Core/Src/IR_CMD_HandlerLogic.c b/Core/Src/IR_CMD_HandlerLogic.c index 55b8f69..c60e1d0 100644 --- a/Core/Src/IR_CMD_HandlerLogic.c +++ b/Core/Src/IR_CMD_HandlerLogic.c @@ -120,6 +120,8 @@ void IR_Home_Process() { default: break; } + }else if(currentInfo.state != RUN){ + startShooting(infoBlock.hwInfo.timings.preRun); } break; @@ -209,8 +211,85 @@ void IR_Home_Process() { // } // led_clear(); break; + { + sound_play_note((Note_t){0, 0, 50},3); + Shot wrShot; + wrShot.isExist = 0xAA; + wrShot.countRepeatShot = 0xBB; + wrShot.rotationAxial = 0xCC; + wrShot.rotationHorizontal = 0xDD; + wrShot.rotationVertical = 0xEE; + wrShot.speedRollerBottom = 0xFF; + wrShot.speedRollerTop = 0x0F; + wrShot.speedScrew = 0xF0; - case IR_FRONT_MID: { + for (int i = 0; i < MAX_SHOT_COUNT; ++i) { + print("SAVE "); + printNumber(i); + print(" -> "); + MemoryStatus saveStat = saveShot(i, &wrShot); + if(saveStat == EEPROM_OK){ + print("OK"); + } else { + print("EEPROM_FAIL"); + } + print(" -> "); + HAL_Delay(100); + print(" READ -> "); + Shot rShoot = {0}; + MemoryStatus status = getShot(i, &rShoot); + print(" "); + switch (status) { + case EEPROM_FAIL: + print("EEPROM_FAIL"); + break; + case EEPROM_MISSING_ELEMENT: + print("EEPROM_MISSING_ELEMENT"); + break; + case EEPROM_OUT_OF_RANGE: + print("EEPROM_OUT_OF_RANGE"); + break; + case EEPROM_WRONG_STARTADDR: + print("EEPROM_WRONG_STARTADDR"); + break; + case EEPROM_OK: + print("EEPROM_OK"); + break; + default: + print("???"); + break; + } + print(" - > "); + if(memcmp(&rShoot, &wrShot, sizeof(Shot)) == 0){ + print("OK\n"); + } else { + print("ERROR !!!!!!!!!!!!!!!!!!!!!\n"); + } + } + print("\n"); + //////////////////////////////////////////// + Program wrProg = {0}; + wrProg.header.countRepeat = 0x11; + wrProg.header.options = 0x22; + wrProg.header.shotCount = 0x33; + memset(&wrProg.shots, 0x44, sizeof(wrProg.shots)); + + + for (int i = 0; i < MAX_PROGRAM_COUNT; ++i){ + + } + //////////////////////////////////////////// + for (int i = 0; i < MAX_MACRO_COUNT; ++i){ + + } + } + break; + + case IR_FRONT_MID: + break; + sound_play_note((Note_t){0, 0, 50},3); + EEPROM_EARSE(); +// { // uint8_t i2c_address; // HAL_StatusTypeDef result; // @@ -237,55 +316,57 @@ void IR_Home_Process() { // } break; - case IR_FRONT_LEFT: { -// uint8_t buf[1024]; // Буфер для чтения данных размером 128 байт -// uint16_t blockAddr16 = START_ADR_MACRO; // Начальный адрес EEPROM -// uint8_t blockAddr[2] = { (uint8_t) (blockAddr16 >> 8), -// (uint8_t) (blockAddr16 & 0xFF) }; // Адрес в формате 2 байта -// int max_attempts = 15; // Максимальное количество попыток для операции -// int attempts = 0; // Счетчик попыток -// HAL_StatusTypeDef status; -// -// do { -// // Отправляем адрес в EEPROM -// status = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), -// blockAddr, 2, 1000); -// if (status != HAL_OK) { -// HAL_Delay(1); // Задержка перед повтором -// attempts++; -// continue; // Переход к следующей попытке -// } -// -// HAL_Delay(1); // Небольшая задержка -// -// // Читаем 128 байт данных из EEPROM -// status = HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1) | 1, -// buf, sizeof(buf), 1000); -// if (status == HAL_OK) { -// // Данные успешно считаны, выводим их -// char buffer[16]; -// for (int i = 0; i < sizeof(buf); ++i) { -// if (i % 8 == 0) -// print(" "); -// if (i % 32 == 0) -// print("\n"); -// -// snprintf(buffer, sizeof(buffer), "%02X ", buf[i]); // Преобразуем байт в шестнадцатеричную строку -// CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer)); -// } -// break; // Выход из попыток, если чтение успешно -// } else { -// print("Read Error EEPROM\n"); -// HAL_Delay(1); // Задержка перед повтором -// attempts++; -// } -// } while (attempts < max_attempts); -// -// if (status != HAL_OK) { -// print("Failed to read EEPROM after multiple attempts\n"); -// } -// print("\n\n\n"); -// } + case IR_FRONT_LEFT: + break; + { + uint8_t buf[1024]; // Буфер для чтения данных размером 128 байт + uint16_t blockAddr16 = START_ADR_SHOT; // Начальный адрес EEPROM + uint8_t blockAddr[2] = { (uint8_t) (blockAddr16 >> 8), + (uint8_t) (blockAddr16 & 0xFF) }; // Адрес в формате 2 байта + int max_attempts = 15; // Максимальное количество попыток для операции + int attempts = 0; // Счетчик попыток + HAL_StatusTypeDef status; + + do { + // Отправляем адрес в EEPROM + status = HAL_I2C_Master_Transmit(&hi2c1, (AT24C_ADRESS << 1), + blockAddr, 2, 1000); + if (status != HAL_OK) { + HAL_Delay(1); // Задержка перед повтором + attempts++; + continue; // Переход к следующей попытке + } + + HAL_Delay(1); // Небольшая задержка + + // Читаем 128 байт данных из EEPROM + status = HAL_I2C_Master_Receive(&hi2c1, (AT24C_ADRESS << 1) | 1, + buf, sizeof(buf), 1000); + if (status == HAL_OK) { + // Данные успешно считаны, выводим их + char buffer[16]; + for (int i = 0; i < sizeof(buf); ++i) { + if (i % 8 == 0) + print(" "); + if (i % 32 == 0) + print("\n"); + + snprintf(buffer, sizeof(buffer), "%02X ", buf[i]); // Преобразуем байт в шестнадцатеричную строку + CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer)); + } + break; // Выход из попыток, если чтение успешно + } else { + print("Read Error EEPROM\n"); + HAL_Delay(1); // Задержка перед повтором + attempts++; + } + } while (attempts < max_attempts); + + if (status != HAL_OK) { + print("Failed to read EEPROM after multiple attempts\n"); + } + print("\n\n\n"); + } break; default: diff --git a/Core/Src/RobotFunctions.c b/Core/Src/RobotFunctions.c index ad07405..d18a8c5 100644 --- a/Core/Src/RobotFunctions.c +++ b/Core/Src/RobotFunctions.c @@ -30,6 +30,10 @@ uint32_t lastIndicationTime = 0; uint32_t noBallTimer = 0; uint32_t noBallTimeout = 0xFFFFFFFF; +uint32_t stop_timer = 0; +uint32_t stop_timer_TIMEOUT = 0; +uint8_t onStopExecuted = 1; + void BallEXT_Handler(); void robotStateStart(uint32_t delayTime); void pauseShooting(); @@ -43,6 +47,12 @@ uint8_t loadShotFromProgram(CurrentProgram *currentProg); uint8_t loadNextProgramInMacro(CurrentMacro *currentMacro); uint8_t loadProgramFromMacro(CurrentMacro *currentMacro); +void setPosOffDelay(uint16_t ms){ + stop_timer = millis(); + stop_timer_TIMEOUT = ms; + onStopExecuted = 0; +} + void robotStateStart(uint32_t delayTime) { currentInfo.state = PRERUN_WAIT; currentInfo.startDelay = delayTime; @@ -58,6 +68,8 @@ void pauseShooting() { void robotStateStop() { currentInfo.state = STOP; + stop_timer = millis(); + onStopExecuted = 0; } long map(long x, long in_min, long in_max, long out_min, long out_max) { @@ -98,6 +110,12 @@ void Robot_INIT() { } led_clear(); melody(melody_start); + + + setPosOffDelay(1000); +// SetServoOFF(0); +// SetServoOFF(1); +// SetServoOFF(2); } void BallEXT() { @@ -105,11 +123,24 @@ void BallEXT() { ballReact_timer = millis(); } +void setPosOff(){ + SetServoOFF(0); + SetServoOFF(1); + SetServoOFF(2); +} + + + void RobotTick() { BallEXT_Handler(); led_tick(); sound_tick(); + if(onStopExecuted == 0 && millis() - stop_timer > stop_timer_TIMEOUT){ + onStopExecuted = 1; + setPosOff(); + } + // No Ball Handler if (currentInfo.state == RUN && millis() - noBallTimer > noBallTimeout) { if(currentInfo.mode == DebugShot){ @@ -128,6 +159,13 @@ void RobotTick() { infoBlock.hwInfo.servos[SERVO_HORIZONTAL].def, infoBlock.hwInfo.servos[SERVO_VERTICAL].min); print("NO BALL!!!"); + + + setPosOffDelay(1000); +// SetServoOFF(0); +// SetServoOFF(1); +// SetServoOFF(2); + } // PreRun delay @@ -174,6 +212,12 @@ uint8_t prepareShot(uint8_t number) { currentInfo.mode = ShotMode; currentInfo.shot.shot = shot; currentInfo.shot.indexGlobal = number; + currentInfo.shot.currentBallCount = 0; + +// setPosDefault(); + Shot* firstShot = ¤tInfo.shot.shot; + setPos(firstShot->rotationAxial, firstShot->rotationHorizontal, firstShot->rotationVertical); + melody(melody_OK); return 1; } else { @@ -192,6 +236,18 @@ uint8_t prepareProgramm(uint8_t number) { currentInfo.mode = ProgramMode; currentInfo.program.program = program; currentInfo.program.indexGlobal = number; + currentInfo.program.currentShotIndexLocal = 0; + currentInfo.program.currentBallCount = 0; + + if (!loadShotFromProgram(¤tInfo.program)) { + print("loadShotFromProgram ERR\n"); + melody(melody_Error); + return 0; + } + + Shot* firstShot = ¤tInfo.program.currentShot.shot; + setPos(firstShot->rotationAxial, firstShot->rotationHorizontal, firstShot->rotationVertical); + melody(melody_OK); return 1; } else { @@ -211,6 +267,24 @@ uint8_t prepareMacro(uint8_t number) { currentInfo.mode = MacroMode; currentInfo.macro.macro = macro; currentInfo.macro.indexGlobal = number; + currentInfo.macro.currentProgramIndexLocal = 0; + currentInfo.macro.currentBallCount = 0; + + if (!loadProgramFromMacro(¤tInfo.macro)) { + print("loadProgramFromMacro ERR\n"); + melody(melody_Error); + return 0; + } + if (!loadShotFromProgram(¤tInfo.macro.currentProgram)) { + print("loadShotFromProgram in macro ERR\n"); + melody(melody_Error); + return 0; + } + + Shot* firstShot = ¤tInfo.macro.currentProgram.currentShot.shot; + setPos(firstShot->rotationAxial, firstShot->rotationHorizontal, firstShot->rotationVertical); + + melody(melody_OK); return 1; } else { @@ -534,7 +608,12 @@ void stopShooting() { setScrewkSpeed(0); setRollersSpeed(100, 100); - setPosDefault(); +// setPosDefault(); + + setPosOffDelay(1000); +// SetServoOFF(0); +// SetServoOFF(1); +// SetServoOFF(2); } void shotApply(CurrentShot *currentShot) { @@ -543,9 +622,10 @@ void shotApply(CurrentShot *currentShot) { shot->rotationVertical); setRollersSpeed(shot->speedRollerTop, shot->speedRollerBottom); setScrewkSpeed(shot->speedScrew); - noBallTimeout = MIN( - calculatePeriod( shot->speedScrew) * NOBALL_TIMEOUT_MULTIPLIER, - 30000); +// noBallTimeout = MIN( +// calculatePeriod( shot->speedScrew) * NOBALL_TIMEOUT_MULTIPLIER, +// 30000); + noBallTimeout = NOBALL_TIMEOUT_HARD; noBallTimer = millis(); ////////////////////////// LED //////////////////////////////////////// diff --git a/Core/Src/main.c b/Core/Src/main.c index e40d6e5..ec33bce 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -178,36 +178,36 @@ int main(void) /* Infinite loop */ /* USER CODE BEGIN WHILE */ - const char* getStateString(State state) { - switch (state) { - case STOP: - return "STOP"; - case RUN: - return "RUN"; - case PAUSE: - return "PAUSE"; - case PRERUN_WAIT: - return "PRERUN_WAIT"; - default: - return "UNKNOWN"; - } - } - const char* getModeString(Mode mode) { - switch (mode) { - case NoneMode: - return "NoneMode"; - case ShotMode: - return "ShotMode"; - case ProgramMode: - return "ProgramMode"; - case MacroMode: - return "MacroMode"; - case DebugShot: - return "DebugShot"; - default: - return "UNKNOWN"; - } - } +// const char* getStateString(State state) { +// switch (state) { +// case STOP: +// return "STOP"; +// case RUN: +// return "RUN"; +// case PAUSE: +// return "PAUSE"; +// case PRERUN_WAIT: +// return "PRERUN_WAIT"; +// default: +// return "UNKNOWN"; +// } +// } +// const char* getModeString(Mode mode) { +// switch (mode) { +// case NoneMode: +// return "NoneMode"; +// case ShotMode: +// return "ShotMode"; +// case ProgramMode: +// return "ProgramMode"; +// case MacroMode: +// return "MacroMode"; +// case DebugShot: +// return "DebugShot"; +// default: +// return "UNKNOWN"; +// } +// } while (1) { @@ -221,16 +221,16 @@ int main(void) // unsigned char text[] = "Hello\n"; // printNumber(SysTick->LOAD); // CDC_Transmit_FS(text, sizeof(text)); - - char buffer[100]; - extern uint32_t vsk1; - extern uint32_t vsk2; - extern uint16_t timing1; - extern uint16_t timing2; - sprintf(buffer, - "timing1: %u ms, timing2: %u ms, vsk1: %u RPM, vsk2: %u RPM\n", - timing1, timing2, vsk1, vsk2); - CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer)); +// +// char buffer[100]; +// extern uint32_t vsk1; +// extern uint32_t vsk2; +// extern uint16_t timing1; +// extern uint16_t timing2; +// sprintf(buffer, +// "timing1: %u ms, timing2: %u ms, vsk1: %u RPM, vsk2: %u RPM\n", +// timing1, timing2, vsk1, vsk2); +// CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer)); // char buffer[64]; // sprintf(buffer, "Current mode: %s, Current state: %s\n", diff --git a/Core/Src/pca9685.c b/Core/Src/pca9685.c index fb1fefc..2ceadee 100644 --- a/Core/Src/pca9685.c +++ b/Core/Src/pca9685.c @@ -35,3 +35,16 @@ void SetServo(uint8_t channel, uint8_t angel) HAL_I2C_Master_Transmit(&hi2c1, (PCA9685_ADRESS << 1), bufer, 5, 10); } +void SetServoOFF(uint8_t channel) +{ + uint8_t bufer[5]; + + bufer[0] = 6 + channel*4; //channel register adress + bufer[1] = 0; //start time for "on" Lowbyte (0..4095) + bufer[2] = 0; //start time for "on" HIbyte + bufer[3] = 0&0xFF; //start time for "off" Lowbyte (0..4095) + bufer[4] = 0>>8;; //start time for "off" HIbyte + + HAL_I2C_Master_Transmit(&hi2c1, (PCA9685_ADRESS << 1), bufer, 5, 10); +} + diff --git a/TODO.md b/TODO.md index 82d954a..0381d42 100644 --- a/TODO.md +++ b/TODO.md @@ -1,8 +1,10 @@ Баги: - При сбоях UART вешает его и иногда не переинициализирует даже после рестарта контроллера + При сбоях UART вешает оранж и иногда не переинициализирует даже после рестарта контроллера + +debug mode todo... Логика: - Ограничение скорости роликов! + V Ограничение скорости роликов! V Ограничение углов сервы V Начальное смещение @@ -39,7 +41,7 @@ IR: V Правильное переключение выстрелов с учётом repeatCount V Переключение выстрелов в программе V Переключение программ в макро - Правильная функция паузы + V Правильная функция паузы Индикация: V Текущий буфер индикации @@ -49,9 +51,9 @@ IR: V Процесс удаления Звук: - Звук приёма IR - Звук ошибки - Звук включения + V Звук приёма IR + V Звук ошибки + V Звук включения