/* #include * splitflap.c * * Created on: 29.09.2022 * Author: jonas */ #include "splitflap.h" #include "McuULN2003.h" #include #include "McuWait.h" #include "lib/dict.h" #include "splitflap_flaps.h" static dict_t **splitFlapDict; void SF_InitConfig(void){ splitFlapDict = dictAlloc(); ((dict_t*)splitFlapDict)->key=NULL; ((dict_t*)splitFlapDict)->value=NULL; ((dict_t*)splitFlapDict)->next=NULL; float stepsPerSegment = SPLITFLAP_STEPS_PER_SEGMENT; // do division once addItem(splitFlapDict, SF_SPACE, (int32_t*)0); addItem(splitFlapDict, SF_A, (int32_t*)(int32_t)(stepsPerSegment * 1.0 + 0.5)); // +0.5 so that the rounding is addItem(splitFlapDict, SF_B, (int32_t*)(int32_t)(stepsPerSegment * 2.0 + 0.5)); // done correctly addItem(splitFlapDict, SF_C, (int32_t*)(int32_t)(stepsPerSegment * 3.0 + 0.5)); addItem(splitFlapDict, SF_D, (int32_t*)(int32_t)(stepsPerSegment * 4.0 + 0.5)); addItem(splitFlapDict, SF_E, (int32_t*)(int32_t)(stepsPerSegment * 5.0 + 0.5)); addItem(splitFlapDict, SF_F, (int32_t*)(int32_t)(stepsPerSegment * 6.0 + 0.5)); addItem(splitFlapDict, SF_G, (int32_t*)(int32_t)(stepsPerSegment * 7.0 + 0.5)); addItem(splitFlapDict, SF_H, (int32_t*)(int32_t)(stepsPerSegment * 8.0 + 0.5)); addItem(splitFlapDict, SF_I, (int32_t*)(int32_t)(stepsPerSegment * 9.0 + 0.5)); addItem(splitFlapDict, SF_J, (int32_t*)(int32_t)(stepsPerSegment * 10.0 + 0.5)); addItem(splitFlapDict, SF_K, (int32_t*)(int32_t)(stepsPerSegment * 11.0 + 0.5)); addItem(splitFlapDict, SF_L, (int32_t*)(int32_t)(stepsPerSegment * 12.0 + 0.5)); addItem(splitFlapDict, SF_M, (int32_t*)(int32_t)(stepsPerSegment * 13.0 + 0.5)); addItem(splitFlapDict, SF_N, (int32_t*)(int32_t)(stepsPerSegment * 14.0 + 0.5)); addItem(splitFlapDict, SF_O, (int32_t*)(int32_t)(stepsPerSegment * 15.0 + 0.5)); addItem(splitFlapDict, SF_P, (int32_t*)(int32_t)(stepsPerSegment * 16.0 + 0.5)); addItem(splitFlapDict, SF_Q, (int32_t*)(int32_t)(stepsPerSegment * 17.0 + 0.5)); addItem(splitFlapDict, SF_R, (int32_t*)(int32_t)(stepsPerSegment * 18.0 + 0.5)); addItem(splitFlapDict, SF_S, (int32_t*)(int32_t)(stepsPerSegment * 19.0 + 0.5)); addItem(splitFlapDict, SF_T, (int32_t*)(int32_t)(stepsPerSegment * 20.0 + 0.5)); addItem(splitFlapDict, SF_U, (int32_t*)(int32_t)(stepsPerSegment * 21.0 + 0.5)); addItem(splitFlapDict, SF_V, (int32_t*)(int32_t)(stepsPerSegment * 22.0 + 0.5)); addItem(splitFlapDict, SF_W, (int32_t*)(int32_t)(stepsPerSegment * 23.0 + 0.5)); addItem(splitFlapDict, SF_X, (int32_t*)(int32_t)(stepsPerSegment * 24.0 + 0.5)); addItem(splitFlapDict, SF_Y, (int32_t*)(int32_t)(stepsPerSegment * 25.0 + 0.5)); addItem(splitFlapDict, SF_Z, (int32_t*)(int32_t)(stepsPerSegment * 26.0 + 0.5)); addItem(splitFlapDict, SF_0, (int32_t*)(int32_t)(stepsPerSegment * 27.0 + 0.5)); addItem(splitFlapDict, SF_1, (int32_t*)(int32_t)(stepsPerSegment * 28.0 + 0.5)); addItem(splitFlapDict, SF_2, (int32_t*)(int32_t)(stepsPerSegment * 29.0 + 0.5)); addItem(splitFlapDict, SF_3, (int32_t*)(int32_t)(stepsPerSegment * 30.0 + 0.5)); addItem(splitFlapDict, SF_4, (int32_t*)(int32_t)(stepsPerSegment * 31.0 + 0.5)); addItem(splitFlapDict, SF_5, (int32_t*)(int32_t)(stepsPerSegment * 32.0 + 0.5)); addItem(splitFlapDict, SF_6, (int32_t*)(int32_t)(stepsPerSegment * 33.0 + 0.5)); addItem(splitFlapDict, SF_7, (int32_t*)(int32_t)(stepsPerSegment * 34.0 + 0.5)); addItem(splitFlapDict, SF_8, (int32_t*)(int32_t)(stepsPerSegment * 35.0 + 0.5)); addItem(splitFlapDict, SF_9, (int32_t*)(int32_t)(stepsPerSegment * 36.0 + 0.5)); addItem(splitFlapDict, SF_EXCLAMATION, (int32_t*)(int32_t)(stepsPerSegment * 37.0 + 0.5)); addItem(splitFlapDict, SF_QUESTION, (int32_t*)(int32_t)(stepsPerSegment * 38.0 + 0.5)); addItem(splitFlapDict, SF_COLON, (int32_t*)(int32_t)(stepsPerSegment * 39.0 + 0.5)); } void SF_DeInitConfig(void){ dictDealoc(splitFlapDict); } SF_Handle_t SF_Init(SF_Config_t* instance, int id){ SF_t* splitflap; #if SPLITFLAP_CONFIG_USE_FREERTOS_HEAP splitflap = (SF_t*)pvPortMalloc(sizeof(SF_t)); /* get a new device descriptor */ #else splitflap = (SF_t*)malloc(sizeof(SF_t)); /* get a new device descriptor */ #endif splitflap->magSensor = McuGPIO_InitGPIO(&instance->magSensorConfig); splitflap->motor = McuULN2003_InitMotor(&instance->motorConfig); splitflap->id = id; return splitflap; } bool SF_MoveMotorToZeroPosition(SF_Handle_t instance, int8_t offsetSegments){ int numStepsMoved = 0; // move out of sensor while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == true){ McuULN2003_IncStep(((SF_t*)instance)->motor); McuWait_Waitms(20); } // turn until sensor is on while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == false && numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND ){ McuULN2003_IncStep(((SF_t*)instance)->motor); McuWait_Waitms(20); numStepsMoved++; } // one more segment if not already one round if(numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND){ // +0.5 so that the rounding is done correctly int8_t offsetSteps = (int8_t)((float)offsetSegments*SPLITFLAP_STEPS_PER_SEGMENT + 0.5); for(int i=0; i < offsetSteps; i++){ McuULN2003_IncStep(((SF_t*)instance)->motor); McuWait_Waitms(20); numStepsMoved++; } } McuULN2003_SetPos(((SF_t*)instance)->motor, 0); McuULN2003_PowerOff(((SF_t*)instance)->motor); // success if less than one rotation return numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND; } void SF_MoveSteps(SF_Handle_t instance, int32_t steps){ // run move with acceleration & deceleration McuULN2003_AccelerationStart(((SF_t*)instance)->motor); while(steps>0){ if(McuULN2003_StepCallback(((SF_t*)instance)->motor, true)){ steps--; } McuWait_Waitms(1); } McuULN2003_AccelerationEnd(((SF_t*)instance)->motor); // Power off disables all outputs of the ULN, // required since it is possible that one is still active, which would result in the motor getting hot // no re-init is required McuULN2003_PowerOff(((SF_t*)instance)->motor); } bool SF_GetMagSensorAtZeroPosition(SF_Handle_t instance){ return McuGPIO_IsLow(((SF_t*)instance)->magSensor); } void SF_MoveToFlap(SF_Handle_t instance, char* flap){ // get flap pos from dictonary int32_t flapPos = (int32_t)getItem(*splitFlapDict, flap); // get current motor pos int32_t currentPos = SF_GetMotorPosition(instance) % SPLITFLAP_STEPS_ONE_ROUND; // calc steps to move int32_t stepsToReachFlap = 0; // not already there if(flapPos != currentPos){ if(flapPos < currentPos){ stepsToReachFlap = SPLITFLAP_STEPS_ONE_ROUND-currentPos+flapPos; }else if(flapPos > currentPos){ stepsToReachFlap = flapPos - currentPos; } SF_MoveSteps(instance, stepsToReachFlap); } } int32_t SF_GetMotorPosition(SF_Handle_t instance){ return McuULN2003_GetPos(((SF_t*)instance)->motor); } void SF_Deinit(SF_Handle_t instance){ McuULN2003_DeinitMotor(((SF_t*)instance)->motor); McuGPIO_DeinitGPIO(((SF_t*)instance)->magSensor); }