Micro-controllers, wireless transmission and database
This project assumes you have already installed STM32CubeIDE. You need to have previously done a basic blink sketch with blue-pill using STM32CubeIDE. I have made a complete video from installing STM32CubeIDE to LED blink program. You can watch it by clicking this link. https://www.youtube.com/watch?v=kXg467nVd_A
Click connectivity --> Click I2C1
For I2C select I2C
/* USER CODE BEGIN 0 */ #define PCA9685_ADDRESS 0x80 // Datasheet link --> https://cdn-shop.adafruit.com/datasheets/PCA9685.pdf #define PCA9685_MODE1 0x0 // as in the datasheet page no 10/52 #define PCA9685_PRE_SCALE 0xFE // as in the datasheet page no 13/52 #define PCA9685_LED0_ON_L 0x6 // as in the datasheet page no 10/52 #define PCA9685_MODE1_SLEEP_BIT 4 // as in the datasheet page no 14/52 #define PCA9685_MODE1_AI_BIT 5 // as in the datasheet page no 14/52 #define PCA9685_MODE1_RESTART_BIT 7 // as in the datasheet page no 14/52 void PCA9685_SetBit(uint8_t Register, uint8_t Bit, uint8_t Value) { uint8_t readValue; // Read all 8 bits and set only one bit to 0/1 and write all 8 bits back HAL_I2C_Mem_Read(&hi2c1, PCA9685_ADDRESS, Register, 1, &readValue, 1, 10); if (Value == 0) readValue &= ~(1 << Bit); else readValue |= (1 << Bit); HAL_I2C_Mem_Write(&hi2c1, PCA9685_ADDRESS, Register, 1, &readValue, 1, 10); HAL_Delay(1); } void PCA9685_SetPWMFrequency(uint16_t frequency) { uint8_t prescale; if(frequency >= 1526) prescale = 0x03; else if(frequency <= 24) prescale = 0xFF; // internal 25 MHz oscillator as in the datasheet page no 1/52 else prescale = 25000000 / (4096 * frequency); // prescale changes 3 to 255 for 1526Hz to 24Hz as in the datasheet page no 1/52 PCA9685_SetBit(PCA9685_MODE1, PCA9685_MODE1_SLEEP_BIT, 1); HAL_I2C_Mem_Write(&hi2c1, PCA9685_ADDRESS, PCA9685_PRE_SCALE, 1, &prescale, 1, 10); PCA9685_SetBit(PCA9685_MODE1, PCA9685_MODE1_SLEEP_BIT, 0); PCA9685_SetBit(PCA9685_MODE1, PCA9685_MODE1_RESTART_BIT, 1); } void PCA9685_Init(uint16_t frequency) { PCA9685_SetPWMFrequency(frequency); // 50 Hz for servo PCA9685_SetBit(PCA9685_MODE1, PCA9685_MODE1_AI_BIT, 1); } void PCA9685_SetPWM(uint8_t Channel, uint16_t OnTime, uint16_t OffTime) { uint8_t registerAddress; uint8_t pwm[4]; registerAddress = PCA9685_LED0_ON_L + (4 * Channel); // See example 1 in the datasheet page no 18/52 pwm[0] = OnTime & 0xFF; pwm[1] = OnTime>>8; pwm[2] = OffTime & 0xFF; pwm[3] = OffTime>>8; HAL_I2C_Mem_Write(&hi2c1, PCA9685_ADDRESS, registerAddress, 1, pwm, 4, 10); } void PCA9685_SetServoAngle(uint8_t Channel, float Angle) { float Value; // 50 Hz servo then 4095 Value --> 20 milliseconds // 0 degree --> 0.5 ms(102.4 Value) and 180 degree --> 2.5 ms(511.9 Value) Value = (Angle * (511.9 - 102.4) / 180.0) + 102.4; PCA9685_SetPWM(Channel, 0, (uint16_t)Value); } /* USER CODE END 0 */ /* USER CODE BEGIN 2 */ PCA9685_Init(50); // 50Hz for servo /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { PCA9685_SetServoAngle(5, 0); PCA9685_SetServoAngle(7, 36); PCA9685_SetServoAngle(9, 72); PCA9685_SetServoAngle(11, 108); PCA9685_SetServoAngle(13, 144); PCA9685_SetServoAngle(15, 180); HAL_Delay(1000); PCA9685_SetServoAngle(5, 36); PCA9685_SetServoAngle(7, 72); PCA9685_SetServoAngle(9, 108); PCA9685_SetServoAngle(11, 144); PCA9685_SetServoAngle(13, 180); PCA9685_SetServoAngle(15, 0); HAL_Delay(1000); PCA9685_SetServoAngle(5, 72); PCA9685_SetServoAngle(7, 108); PCA9685_SetServoAngle(9, 144); PCA9685_SetServoAngle(11, 180); PCA9685_SetServoAngle(13, 0); PCA9685_SetServoAngle(15, 36); HAL_Delay(1000); PCA9685_SetServoAngle(5, 108); PCA9685_SetServoAngle(7, 144); PCA9685_SetServoAngle(9, 180); PCA9685_SetServoAngle(11, 0); PCA9685_SetServoAngle(13, 36); PCA9685_SetServoAngle(15, 72); HAL_Delay(1000); PCA9685_SetServoAngle(5, 144); PCA9685_SetServoAngle(7, 180); PCA9685_SetServoAngle(9, 0); PCA9685_SetServoAngle(11, 36); PCA9685_SetServoAngle(13, 72); PCA9685_SetServoAngle(15, 108); HAL_Delay(1000); PCA9685_SetServoAngle(5, 180); PCA9685_SetServoAngle(7, 0); PCA9685_SetServoAngle(9, 36); PCA9685_SetServoAngle(11, 72); PCA9685_SetServoAngle(13, 108); PCA9685_SetServoAngle(15, 144); HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */