Working servos (almost) and cleaned robot.h/.c for both controllers
This commit is contained in:
parent
d8d504fdc1
commit
c5bcc17529
|
|
@ -18,6 +18,7 @@ add_executable(main_controller
|
||||||
src/main.c
|
src/main.c
|
||||||
src/robot.c
|
src/robot.c
|
||||||
src/motors.c
|
src/motors.c
|
||||||
|
src/servos.c
|
||||||
src/motion_control.c
|
src/motion_control.c
|
||||||
src/i2c/i2c_master.c
|
src/i2c/i2c_master.c
|
||||||
src/i2c/gyro.c
|
src/i2c/gyro.c
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,23 @@
|
||||||
#define MOTION_CONTROL_H
|
#define MOTION_CONTROL_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define I2C_MOTION_CONTROLLER_ADDRESS 0x09
|
#define I2C_MOTION_CONTROLLER_ADDRESS 0x09
|
||||||
|
|
||||||
typedef struct motion_control_data_t {
|
typedef struct motion_control_data_t {
|
||||||
int16_t target_speed;
|
int16_t target_speed;
|
||||||
float target_angle;
|
float target_angle;
|
||||||
|
|
||||||
|
int16_t motor1_speed;
|
||||||
|
int16_t motor2_speed;
|
||||||
|
bool led_state;
|
||||||
} motion_control_data_t;
|
} motion_control_data_t;
|
||||||
|
|
||||||
void motion_control_init(void);
|
void motion_control_init(void);
|
||||||
|
|
||||||
void motion_control_update(void);
|
void motion_control_update(void);
|
||||||
|
|
||||||
|
void motion_control_send(void);
|
||||||
|
|
||||||
#endif // MOTION_CONTROL_H
|
#endif // MOTION_CONTROL_H
|
||||||
|
|
@ -2,16 +2,20 @@
|
||||||
#define ROBOT_H
|
#define ROBOT_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "i2c/headers/mcp23017.h"
|
|
||||||
#include "i2c/headers/gyro.h"
|
#include "i2c/headers/gyro.h"
|
||||||
#include "motion_control.h"
|
#include "i2c/headers/mcp23017.h"
|
||||||
|
#include "headers/motion_control.h"
|
||||||
|
#include "headers/servos.h"
|
||||||
#include "wifi/headers/udp_client.h"
|
#include "wifi/headers/udp_client.h"
|
||||||
|
|
||||||
typedef struct robot_t {
|
typedef struct robot_t {
|
||||||
udp_client_t udp_client;
|
|
||||||
mcp23017_data_t mcp23017_data;
|
|
||||||
gyro_data_t gyro_data;
|
gyro_data_t gyro_data;
|
||||||
|
mcp23017_data_t mcp23017_data;
|
||||||
|
|
||||||
motion_control_data_t motion_control_data;
|
motion_control_data_t motion_control_data;
|
||||||
|
servos_data_t servos_data;
|
||||||
|
|
||||||
|
udp_client_t udp_client;
|
||||||
|
|
||||||
bool is_running;
|
bool is_running;
|
||||||
float delta_time_ms;
|
float delta_time_ms;
|
||||||
|
|
@ -22,7 +26,7 @@ extern robot_t robot;
|
||||||
// Init all robot's components
|
// Init all robot's components
|
||||||
void robot_init(void);
|
void robot_init(void);
|
||||||
// Handle inputs and outputs
|
// Handle inputs and outputs
|
||||||
void robot_handle_inputs_outputs(void);
|
void robot_update(void);
|
||||||
// Deinit all robot's components
|
// Deinit all robot's components
|
||||||
void robot_deinit(void);
|
void robot_deinit(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef SERVOS_H
|
||||||
|
#define SERVOS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef enum servos_t {
|
||||||
|
SERVO1,
|
||||||
|
SERVO2,
|
||||||
|
SERVO3,
|
||||||
|
|
||||||
|
NB_SERVOS
|
||||||
|
} servos_t;
|
||||||
|
|
||||||
|
typedef struct servos_data_t {
|
||||||
|
uint16_t servos_pos[NB_SERVOS];
|
||||||
|
} servos_data_t;
|
||||||
|
|
||||||
|
void servos_init(void);
|
||||||
|
|
||||||
|
void servo_set_angle(servos_t servo, uint16_t pos);
|
||||||
|
|
||||||
|
#endif // SERVOS_H
|
||||||
|
|
@ -18,7 +18,7 @@ int main(void)
|
||||||
|
|
||||||
while(robot.is_running)
|
while(robot.is_running)
|
||||||
{
|
{
|
||||||
robot_handle_inputs_outputs();
|
robot_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
robot_deinit();
|
robot_deinit();
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,29 @@
|
||||||
#include <hardware/i2c.h>
|
#include <hardware/i2c.h>
|
||||||
#include "i2c/headers/i2c_master.h"
|
#include "i2c/headers/i2c_master.h"
|
||||||
#include "headers/motors.h"
|
#include "headers/motors.h"
|
||||||
|
#include "headers/servos.h"
|
||||||
#include "headers/robot.h"
|
#include "headers/robot.h"
|
||||||
|
|
||||||
#define ANGLE_PER_S 90.0f
|
#define ANGLE_PER_S 90.0f
|
||||||
#define GAIN_KP 10
|
#define GAIN_KP 10
|
||||||
|
|
||||||
#define MSG_LEN sizeof(uint8_t) * 2
|
#define MSG_LEN sizeof(uint8_t) + /* 0x00 */ \
|
||||||
#define MSG_DELAY_MS 5.0f
|
sizeof(uint8_t) + /* LED */ \
|
||||||
|
sizeof(uint8_t) * NB_MOTORS + /* Motors */ \
|
||||||
|
sizeof(uint16_t) * NB_SERVOS /* Servos */
|
||||||
|
|
||||||
|
#define MSG_DELAY_MS 2.0f
|
||||||
|
|
||||||
void motion_control_init(void)
|
void motion_control_init(void)
|
||||||
{
|
{
|
||||||
|
robot.motion_control_data.led_state = false;
|
||||||
robot.motion_control_data.target_speed = 0;
|
robot.motion_control_data.target_speed = 0;
|
||||||
robot.motion_control_data.target_angle = 0.0f;
|
robot.motion_control_data.target_angle = 0.0f;
|
||||||
|
robot.motion_control_data.motor1_speed = 0;
|
||||||
|
robot.motion_control_data.motor2_speed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void motion_control_update(void)
|
static inline void motors_control_update(void)
|
||||||
{
|
{
|
||||||
// First we update motion control data from received data
|
// First we update motion control data from received data
|
||||||
robot.motion_control_data.target_angle += (float)robot.udp_client.data.hard.inputs.joystick_y / 256.0f * robot.delta_time_ms / 1000.0f * ANGLE_PER_S;
|
robot.motion_control_data.target_angle += (float)robot.udp_client.data.hard.inputs.joystick_y / 256.0f * robot.delta_time_ms / 1000.0f * ANGLE_PER_S;
|
||||||
|
|
@ -46,8 +54,6 @@ void motion_control_update(void)
|
||||||
|
|
||||||
//printf(">target_speed:%d\n", robot.motion_control_data.target_speed);
|
//printf(">target_speed:%d\n", robot.motion_control_data.target_speed);
|
||||||
|
|
||||||
float target_angle_radian = robot.motion_control_data.target_angle / 180.0f * M_PI;
|
|
||||||
|
|
||||||
float error = robot.motion_control_data.target_angle - robot.gyro_data.x_angle;
|
float error = robot.motion_control_data.target_angle - robot.gyro_data.x_angle;
|
||||||
while(error > 180) error -= 360;
|
while(error > 180) error -= 360;
|
||||||
while(error < -180) error += 360;
|
while(error < -180) error += 360;
|
||||||
|
|
@ -65,19 +71,69 @@ void motion_control_update(void)
|
||||||
correction = 150;
|
correction = 150;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
float motor1_speed = (float)robot.motion_control_data.target_speed - correction;
|
robot.motion_control_data.motor1_speed = (int16_t)((float)robot.motion_control_data.target_speed - correction);
|
||||||
float motor2_speed = (float)robot.motion_control_data.target_speed + correction;
|
robot.motion_control_data.motor2_speed = (int16_t)((float)robot.motion_control_data.target_speed + correction);
|
||||||
|
|
||||||
if(motor1_speed > 255) motor1_speed = 255;
|
if(robot.motion_control_data.motor1_speed > 255) robot.motion_control_data.motor1_speed = 255;
|
||||||
if(motor2_speed > 255) motor2_speed = 255;
|
if(robot.motion_control_data.motor2_speed > 255) robot.motion_control_data.motor2_speed = 255;
|
||||||
|
|
||||||
if(motor1_speed < -255) motor1_speed = -255;
|
if(robot.motion_control_data.motor1_speed < -255) robot.motion_control_data.motor1_speed = -255;
|
||||||
if(motor2_speed < -255) motor2_speed = -255;
|
if(robot.motion_control_data.motor2_speed < -255) robot.motion_control_data.motor2_speed = -255;
|
||||||
|
|
||||||
// Set dir pins
|
// Set dir pins
|
||||||
motor_set_dir(MOTOR1, (int16_t)motor1_speed);
|
motor_set_dir(MOTOR1, robot.motion_control_data.motor1_speed);
|
||||||
motor_set_dir(MOTOR2, (int16_t)motor2_speed);
|
motor_set_dir(MOTOR2, robot.motion_control_data.motor2_speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void servos_control_update(void)
|
||||||
|
{
|
||||||
|
const uint16_t SERVO1_POSITIONS[5] = {
|
||||||
|
500,
|
||||||
|
// MORE TO DO
|
||||||
|
1950,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint16_t SERVO2_POSITIONS[2] = {
|
||||||
|
600,
|
||||||
|
2850,
|
||||||
|
};
|
||||||
|
|
||||||
|
// XXX DOESN'T WORK ??
|
||||||
|
const uint16_t SERVO3_POSITIONS[2] = {
|
||||||
|
600,
|
||||||
|
2850,
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
// toggle servo 1 pos if button green is pressed
|
||||||
|
static float servo1_toggle_elapsed_time = 0.0f;
|
||||||
|
servo1_toggle_elapsed_time += robot.delta_time_ms;
|
||||||
|
|
||||||
|
if(robot.udp_client.data.hard.inputs.buttons.button_green && servo1_toggle_elapsed_time >= 200.0f)
|
||||||
|
{
|
||||||
|
servo1_toggle_elapsed_time = 0.0f;
|
||||||
|
|
||||||
|
servo_set_angle(SERVO1, 90 - robot.servos_data.servos_pos[SERVO1]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//servo_set_angle(SERVO3, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
void steppers_control_update(void)
|
||||||
|
{
|
||||||
|
steppers_set_pos(48);
|
||||||
|
}
|
||||||
|
|
||||||
|
void motion_control_update(void)
|
||||||
|
{
|
||||||
|
motors_control_update();
|
||||||
|
|
||||||
|
servos_control_update();
|
||||||
|
|
||||||
|
steppers_control_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void motion_control_send(void)
|
||||||
|
{
|
||||||
static float elapsed_time_ms = 0.0f;
|
static float elapsed_time_ms = 0.0f;
|
||||||
elapsed_time_ms += robot.delta_time_ms;
|
elapsed_time_ms += robot.delta_time_ms;
|
||||||
|
|
||||||
|
|
@ -85,19 +141,22 @@ void motion_control_update(void)
|
||||||
{
|
{
|
||||||
elapsed_time_ms = 0;
|
elapsed_time_ms = 0;
|
||||||
// Send motors speed via I2C
|
// Send motors speed via I2C
|
||||||
uint8_t data[5];
|
uint8_t data[MSG_LEN] = {
|
||||||
|
0x00,
|
||||||
|
(uint8_t)robot.motion_control_data.led_state,
|
||||||
|
(uint8_t)abs(robot.motion_control_data.motor1_speed),
|
||||||
|
(uint8_t)abs(robot.motion_control_data.motor2_speed),
|
||||||
|
(uint8_t)(robot.servos_data.servos_pos[SERVO1] >> 8) & 0xFF,
|
||||||
|
(uint8_t)(robot.servos_data.servos_pos[SERVO1]) & 0xFF,
|
||||||
|
(uint8_t)(robot.servos_data.servos_pos[SERVO2] >> 8) & 0xFF,
|
||||||
|
(uint8_t)(robot.servos_data.servos_pos[SERVO2]) & 0xFF,
|
||||||
|
(uint8_t)(robot.servos_data.servos_pos[SERVO3] >> 8) & 0xFF,
|
||||||
|
(uint8_t)(robot.servos_data.servos_pos[SERVO3]) & 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
data[0] = 0x00; /// registre
|
if(i2c_write_blocking(I2C_MASTER_INSTANCE, I2C_MOTION_CONTROLLER_ADDRESS, data, MSG_LEN, false) == PICO_ERROR_GENERIC)
|
||||||
|
|
||||||
data[1] = (uint8_t)abs((int)motor1_speed);
|
|
||||||
data[2] = (uint8_t)abs((int)motor2_speed);
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t reg = 0x00;
|
|
||||||
|
|
||||||
if(i2c_write_blocking(I2C_MASTER_INSTANCE, I2C_MOTION_CONTROLLER_ADDRESS, data, 3, false) == PICO_ERROR_GENERIC)
|
|
||||||
{
|
{
|
||||||
puts("Motion controller not reachable");
|
puts("Motion controller not reachable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
#include <pico/types.h>
|
#include <pico/types.h>
|
||||||
#include "i2c/headers/mcp23017.h"
|
#include "i2c/headers/mcp23017.h"
|
||||||
|
|
||||||
#define MOTOR1_DIR1_MCP23017_GPIO 12
|
#define MCP23017_MOTOR1_DIR1_GPIO 12
|
||||||
#define MOTOR1_DIR2_MCP23017_GPIO 13
|
#define MCP23017_MOTOR1_DIR2_GPIO 13
|
||||||
#define MOTOR2_DIR1_MCP23017_GPIO 14
|
#define MCP23017_MOTOR2_DIR1_GPIO 14
|
||||||
#define MOTOR2_DIR2_MCP23017_GPIO 15
|
#define MCP23017_MOTOR2_DIR2_GPIO 15
|
||||||
|
|
||||||
void motor_set_dir(motors_t motor, int16_t value)
|
void motor_set_dir(motors_t motor, int16_t value)
|
||||||
{
|
{
|
||||||
|
|
@ -16,16 +16,16 @@ void motor_set_dir(motors_t motor, int16_t value)
|
||||||
switch(motor)
|
switch(motor)
|
||||||
{
|
{
|
||||||
case MOTOR1:
|
case MOTOR1:
|
||||||
gpio_dir1_pin = MOTOR1_DIR1_MCP23017_GPIO;
|
gpio_dir1_pin = MCP23017_MOTOR1_DIR1_GPIO;
|
||||||
gpio_dir2_pin = MOTOR1_DIR2_MCP23017_GPIO;
|
gpio_dir2_pin = MCP23017_MOTOR1_DIR2_GPIO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOTOR2:
|
case MOTOR2:
|
||||||
gpio_dir1_pin = MOTOR2_DIR1_MCP23017_GPIO;
|
gpio_dir1_pin = MCP23017_MOTOR2_DIR1_GPIO;
|
||||||
gpio_dir2_pin = MOTOR2_DIR2_MCP23017_GPIO;
|
gpio_dir2_pin = MCP23017_MOTOR2_DIR2_GPIO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ void robot_init(void)
|
||||||
|
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true);
|
||||||
|
|
||||||
|
// I2C and devices
|
||||||
i2c_master_init();
|
i2c_master_init();
|
||||||
|
|
||||||
mcp23017_init();
|
mcp23017_init();
|
||||||
|
|
@ -31,31 +32,15 @@ void robot_init(void)
|
||||||
|
|
||||||
motion_control_init();
|
motion_control_init();
|
||||||
|
|
||||||
if(wifi_operator_init()){
|
// WiFi
|
||||||
while(1){
|
if(wifi_operator_init())
|
||||||
printf("No Wifi\n");
|
robot.is_running = false;
|
||||||
robot.is_running = false;
|
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true);
|
|
||||||
sleep_ms(50);
|
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, false);
|
|
||||||
sleep_ms(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(udp_client_init()){
|
if(udp_client_init())
|
||||||
while(1){
|
robot.is_running = false;
|
||||||
printf("No UDP\n");
|
|
||||||
robot.is_running = false;
|
// Initialisation ended, loop forever if inititalisation failed
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true);
|
for(uint i = 0, led_state = false; robot.is_running ? (i < 5) : true; i++)
|
||||||
sleep_ms(50);
|
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, false);
|
|
||||||
sleep_ms(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialisation ended
|
|
||||||
for(uint8_t i = 0, led_state = true; i < 5; i++)
|
|
||||||
{
|
{
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_state);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_state);
|
||||||
|
|
||||||
|
|
@ -63,7 +48,6 @@ void robot_init(void)
|
||||||
|
|
||||||
led_state = !led_state;
|
led_state = !led_state;
|
||||||
}
|
}
|
||||||
printf(">robot_running:%d\n", robot.is_running);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void update_time(void)
|
static inline void update_time(void)
|
||||||
|
|
@ -76,21 +60,18 @@ static inline void update_time(void)
|
||||||
static float elapsed_time_ms = 0.0f;
|
static float elapsed_time_ms = 0.0f;
|
||||||
elapsed_time_ms += robot.delta_time_ms;
|
elapsed_time_ms += robot.delta_time_ms;
|
||||||
|
|
||||||
static bool led_state = false;
|
|
||||||
if(elapsed_time_ms >= 1000.0f)
|
if(elapsed_time_ms >= 1000.0f)
|
||||||
{
|
{
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_state);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, robot.motion_control_data.led_state);
|
||||||
|
|
||||||
elapsed_time_ms = 0.0f;
|
elapsed_time_ms = 0.0f;
|
||||||
led_state = !led_state;
|
|
||||||
|
robot.motion_control_data.led_state = !robot.motion_control_data.led_state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void robot_handle_inputs_outputs(void)
|
void robot_update(void)
|
||||||
{
|
{
|
||||||
static bool led_state=false;
|
|
||||||
static uint32_t temps_ms_old =0, timer_200_ms=0;
|
|
||||||
uint32_t temps_ms;
|
|
||||||
update_time();
|
update_time();
|
||||||
|
|
||||||
cyw43_arch_poll();
|
cyw43_arch_poll();
|
||||||
|
|
@ -99,17 +80,11 @@ void robot_handle_inputs_outputs(void)
|
||||||
|
|
||||||
motion_control_update();
|
motion_control_update();
|
||||||
|
|
||||||
|
motion_control_send();
|
||||||
|
|
||||||
mcp23017_update();
|
mcp23017_update();
|
||||||
|
|
||||||
temps_ms = to_ms_since_boot(get_absolute_time());
|
tight_loop_contents();
|
||||||
timer_200_ms += temps_ms - temps_ms_old;
|
|
||||||
temps_ms_old = temps_ms;
|
|
||||||
if(timer_200_ms > 200){
|
|
||||||
timer_200_ms = 0;
|
|
||||||
led_state= !led_state;
|
|
||||||
uint8_t data[] = {0x02, led_state};
|
|
||||||
int ret = i2c_write_blocking(I2C_MASTER_INSTANCE, 0x09, data, 2, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void robot_deinit(void)
|
void robot_deinit(void)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "headers/servos.h"
|
||||||
|
|
||||||
|
#include "headers/robot.h"
|
||||||
|
|
||||||
|
void servos_init(void)
|
||||||
|
{
|
||||||
|
for(size_t servo = SERVO1; servo < NB_SERVOS; servo++)
|
||||||
|
robot.servos_data.servos_pos[servo] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void servo_set_angle(servos_t servo, uint16_t pos)
|
||||||
|
{
|
||||||
|
robot.servos_data.servos_pos[servo] = pos;
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ add_executable(motion_controller
|
||||||
src/robot.c
|
src/robot.c
|
||||||
src/i2c/i2c_slave.c
|
src/i2c/i2c_slave.c
|
||||||
src/motors.c
|
src/motors.c
|
||||||
|
src/servos.c
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(motion_controller PRIVATE
|
target_include_directories(motion_controller PRIVATE
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,18 @@
|
||||||
#include <pico/stdlib.h>
|
#include <pico/stdlib.h>
|
||||||
|
|
||||||
// Motors
|
// Motors
|
||||||
typedef enum motors_enum_t {
|
typedef enum motors_t {
|
||||||
MOTOR1,
|
MOTOR1,
|
||||||
MOTOR2,
|
MOTOR2,
|
||||||
|
|
||||||
NB_MOTORS
|
NB_MOTORS
|
||||||
} motors_enum_t;
|
} motors_t;
|
||||||
|
|
||||||
#define MOTOR1_PWM_PIN 9
|
#define I2C_BUFFER_MOTOR1_SPEED 1
|
||||||
#define MOTOR2_PWM_PIN 8
|
#define I2C_BUFFER_MOTOR2_SPEED 2
|
||||||
|
|
||||||
// Init all motors defined in the MOTORS_DEF array
|
// Init all motors defined in the MOTORS_DEF array
|
||||||
void motors_init(void);
|
void motors_init(void);
|
||||||
// Set [motor] in motor_enum_t at [value] between -127 and 128
|
|
||||||
void motor_set_speed(motors_enum_t motor, uint8_t value);
|
|
||||||
// Update motors from the data in the i2c buffer
|
// Update motors from the data in the i2c buffer
|
||||||
void motors_update(void);
|
void motors_update(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ typedef struct robot_t {
|
||||||
i2c_buffer_t i2c_buffer;
|
i2c_buffer_t i2c_buffer;
|
||||||
|
|
||||||
bool is_running;
|
bool is_running;
|
||||||
double delta_time_ms;
|
float delta_time_ms;
|
||||||
} robot_t;
|
} robot_t;
|
||||||
|
|
||||||
extern robot_t robot;
|
extern robot_t robot;
|
||||||
|
|
@ -15,7 +15,7 @@ extern robot_t robot;
|
||||||
// Init all robot's components
|
// Init all robot's components
|
||||||
void robot_init(void);
|
void robot_init(void);
|
||||||
// Handle inputs and outputs
|
// Handle inputs and outputs
|
||||||
void robot_handle_inputs_outputs(void);
|
void robot_update(void);
|
||||||
// Deinit all robot's components
|
// Deinit all robot's components
|
||||||
void robot_deinit(void);
|
void robot_deinit(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef SERVOS_H
|
||||||
|
#define SERVOS_H
|
||||||
|
|
||||||
|
typedef enum servos_t {
|
||||||
|
SERVO1,
|
||||||
|
SERVO2,
|
||||||
|
SERVO3,
|
||||||
|
|
||||||
|
NB_SERVOS
|
||||||
|
} servos_t;
|
||||||
|
|
||||||
|
#define I2C_BUFFER_SERVO1_ANGLE_H 3
|
||||||
|
#define I2C_BUFFER_SERVO1_ANGLE_L 4
|
||||||
|
#define I2C_BUFFER_SERVO2_ANGLE_H 5
|
||||||
|
#define I2C_BUFFER_SERVO2_ANGLE_L 6
|
||||||
|
#define I2C_BUFFER_SERVO3_ANGLE_H 7
|
||||||
|
#define I2C_BUFFER_SERVO3_ANGLE_L 8
|
||||||
|
|
||||||
|
void servos_init(void);
|
||||||
|
|
||||||
|
void servos_update(void);
|
||||||
|
|
||||||
|
#endif // SERVOS_H
|
||||||
|
|
@ -25,7 +25,4 @@ void init_i2c_slave(void);
|
||||||
// Deinit i2c slave
|
// Deinit i2c slave
|
||||||
void deinit_i2c_slave(void);
|
void deinit_i2c_slave(void);
|
||||||
|
|
||||||
uint8_t get_vitesse_moteur_1(void);
|
|
||||||
uint8_t get_vitesse_moteur_2(void);
|
|
||||||
|
|
||||||
#endif // I2C_SLAVE_H
|
#endif // I2C_SLAVE_H
|
||||||
|
|
@ -9,38 +9,35 @@
|
||||||
#include <hardware/gpio.h>
|
#include <hardware/gpio.h>
|
||||||
#include <hardware/i2c.h>
|
#include <hardware/i2c.h>
|
||||||
#include "pico/i2c_slave.h"
|
#include "pico/i2c_slave.h"
|
||||||
|
#include "headers/robot.h"
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
extern i2c_buffer_t i2c_buffer;
|
|
||||||
|
|
||||||
void i2c_slave_buffer_handler(i2c_inst_t *i2c, i2c_slave_event_t event)
|
void i2c_slave_buffer_handler(i2c_inst_t *i2c, i2c_slave_event_t event)
|
||||||
{
|
{
|
||||||
switch(event)
|
switch(event)
|
||||||
{
|
{
|
||||||
case I2C_SLAVE_RECEIVE: // master has written some data
|
case I2C_SLAVE_RECEIVE: // master has written some data
|
||||||
if(!i2c_buffer.buffer_reg_written)
|
if(!robot.i2c_buffer.buffer_reg_written)
|
||||||
{
|
{
|
||||||
// writes always start with the memory address
|
// writes always start with the memory address
|
||||||
i2c_buffer.buffer_reg = i2c_read_byte_raw(I2C_SLAVE_INSTANCE);
|
robot.i2c_buffer.buffer_reg = i2c_read_byte_raw(I2C_SLAVE_INSTANCE);
|
||||||
i2c_buffer.buffer_reg_written = true;
|
robot.i2c_buffer.buffer_reg_written = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// save into memory
|
// save into memory
|
||||||
i2c_buffer.buffer[i2c_buffer.buffer_reg] = i2c_read_byte_raw(I2C_SLAVE_INSTANCE);
|
robot.i2c_buffer.buffer[robot.i2c_buffer.buffer_reg] = i2c_read_byte_raw(I2C_SLAVE_INSTANCE);
|
||||||
i2c_buffer.buffer_reg++;
|
robot.i2c_buffer.buffer_reg++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case I2C_SLAVE_REQUEST: // master is requesting data
|
case I2C_SLAVE_REQUEST: // master is requesting data
|
||||||
// load from memory
|
// load from memory
|
||||||
i2c_write_byte_raw(I2C_SLAVE_INSTANCE, i2c_buffer.buffer[i2c_buffer.buffer_reg]);
|
i2c_write_byte_raw(I2C_SLAVE_INSTANCE, robot.i2c_buffer.buffer[robot.i2c_buffer.buffer_reg]);
|
||||||
i2c_buffer.buffer_reg++;
|
robot.i2c_buffer.buffer_reg++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case I2C_SLAVE_FINISH: // master has signalled Stop / Restart
|
case I2C_SLAVE_FINISH: // master has signalled Stop / Restart
|
||||||
i2c_buffer.buffer_reg_written = false;
|
robot.i2c_buffer.buffer_reg_written = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -70,11 +67,3 @@ void deinit_i2c_slave(void)
|
||||||
// New SDK method to reset i2c slave
|
// New SDK method to reset i2c slave
|
||||||
i2c_slave_deinit(I2C_SLAVE_INSTANCE);
|
i2c_slave_deinit(I2C_SLAVE_INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t get_vitesse_moteur_1(void){
|
|
||||||
return i2c_buffer.buffer[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t get_vitesse_moteur_2(void){
|
|
||||||
return i2c_buffer.buffer[1];
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -8,38 +8,20 @@
|
||||||
* Ce Pico est un esclave piloté par le Pico Principal. *
|
* Ce Pico est un esclave piloté par le Pico Principal. *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#include <pico/stdlib.h>
|
#include "headers/robot.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include "i2c/headers/i2c_slave.h"
|
|
||||||
#include "headers/motors.h"
|
|
||||||
|
|
||||||
|
robot_t robot;
|
||||||
|
|
||||||
i2c_buffer_t i2c_buffer;
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
stdio_init_all();
|
robot_init();
|
||||||
|
|
||||||
sleep_ms(1000);
|
while(robot.is_running)
|
||||||
|
|
||||||
puts("STDIO INIT ALL DONE");
|
|
||||||
|
|
||||||
init_i2c_slave();
|
|
||||||
|
|
||||||
puts("SLAVE INIT DONE");
|
|
||||||
|
|
||||||
gpio_init(PICO_DEFAULT_LED_PIN);
|
|
||||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
|
||||||
|
|
||||||
motors_init();
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
{
|
||||||
gpio_put(PICO_DEFAULT_LED_PIN, i2c_buffer.buffer[2]);
|
robot_update();
|
||||||
motors_update();
|
|
||||||
sleep_ms(10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
robot_deinit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
#include "headers/motors.h"
|
#include "headers/motors.h"
|
||||||
#include "i2c/headers/i2c_slave.h"
|
|
||||||
|
|
||||||
#include <pico/stdlib.h>
|
#include <pico/stdlib.h>
|
||||||
#include <hardware/pwm.h>
|
#include <hardware/pwm.h>
|
||||||
#include <headers/robot.h>
|
#include "headers/robot.h"
|
||||||
|
|
||||||
|
#define MOTOR1_PWM_PIN 9
|
||||||
|
#define MOTOR2_PWM_PIN 8
|
||||||
|
|
||||||
#include <stdio.h>
|
static inline uint get_motor_pwm_pin(motors_t motor)
|
||||||
|
|
||||||
static inline uint get_motor_pwm_pin(motors_enum_t motor)
|
|
||||||
{
|
{
|
||||||
switch(motor)
|
switch(motor)
|
||||||
{
|
{
|
||||||
|
|
@ -23,10 +22,16 @@ static inline uint get_motor_pwm_pin(motors_enum_t motor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void motor_set_speed(motors_t motor, uint8_t value)
|
||||||
|
{
|
||||||
|
uint MOTOR_PWM_PIN = get_motor_pwm_pin(motor);
|
||||||
|
pwm_set_gpio_level(MOTOR_PWM_PIN, (uint16_t)value);
|
||||||
|
}
|
||||||
|
|
||||||
// Init all motors defined in the MOTORS_DEF array
|
// Init all motors defined in the MOTORS_DEF array
|
||||||
void motors_init(void)
|
void motors_init(void)
|
||||||
{
|
{
|
||||||
for(motors_enum_t motor = MOTOR1; motor < NB_MOTORS; motor++)
|
for(motors_t motor = MOTOR1; motor < NB_MOTORS; motor++)
|
||||||
{
|
{
|
||||||
// Init PWM
|
// Init PWM
|
||||||
const uint MOTOR_PWM_PIN = get_motor_pwm_pin(motor);
|
const uint MOTOR_PWM_PIN = get_motor_pwm_pin(motor);
|
||||||
|
|
@ -44,15 +49,8 @@ void motors_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set [motor] in motor_enum_t at [value] between 0 and 255
|
|
||||||
void motor_set_speed(motors_enum_t motor, uint8_t value)
|
|
||||||
{
|
|
||||||
uint MOTOR_PWM_PIN = get_motor_pwm_pin(motor);
|
|
||||||
pwm_set_gpio_level(MOTOR_PWM_PIN, (uint16_t)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void motors_update(void)
|
void motors_update(void)
|
||||||
{
|
{
|
||||||
motor_set_speed(MOTOR1, get_vitesse_moteur_1());
|
motor_set_speed(MOTOR1, robot.i2c_buffer.buffer[I2C_BUFFER_MOTOR1_SPEED]);
|
||||||
motor_set_speed(MOTOR2, get_vitesse_moteur_2());
|
motor_set_speed(MOTOR2, robot.i2c_buffer.buffer[I2C_BUFFER_MOTOR2_SPEED]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <pico/stdlib.h>
|
#include <pico/stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "headers/motors.h"
|
#include "headers/motors.h"
|
||||||
|
#include "headers/servos.h"
|
||||||
#include "i2c/headers/i2c_slave.h"
|
#include "i2c/headers/i2c_slave.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -17,12 +18,14 @@ void robot_init(void)
|
||||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||||
gpio_put(PICO_DEFAULT_LED_PIN, true);
|
gpio_put(PICO_DEFAULT_LED_PIN, true);
|
||||||
|
|
||||||
//motors_init();
|
motors_init();
|
||||||
|
|
||||||
|
servos_init();
|
||||||
|
|
||||||
init_i2c_slave();
|
init_i2c_slave();
|
||||||
|
|
||||||
// Initialisation ended
|
// Initialisation ended, loop forever if initialisation failed
|
||||||
for(uint i = 0, led_state = false; i < 5; i++)
|
for(uint i = 0, led_state = false; robot.is_running ? (i < 5) : true; i++)
|
||||||
{
|
{
|
||||||
gpio_put(PICO_DEFAULT_LED_PIN, led_state);
|
gpio_put(PICO_DEFAULT_LED_PIN, led_state);
|
||||||
|
|
||||||
|
|
@ -34,31 +37,23 @@ void robot_init(void)
|
||||||
|
|
||||||
static inline void update_time(void)
|
static inline void update_time(void)
|
||||||
{
|
{
|
||||||
static bool led_state = false;
|
static float last_time = 0.0f;
|
||||||
static double last_time = 0.0;
|
float start_time = (float)clock() * 1000.0f / (float)CLOCKS_PER_SEC;
|
||||||
double start_time = (double)clock() * 1000.0 / (double)CLOCKS_PER_SEC;
|
|
||||||
robot.delta_time_ms = start_time - last_time;
|
robot.delta_time_ms = start_time - last_time;
|
||||||
last_time = start_time;
|
last_time = start_time;
|
||||||
|
|
||||||
static double elapsed_time = 0.0;
|
gpio_put(PICO_DEFAULT_LED_PIN, robot.i2c_buffer.buffer[0]);
|
||||||
elapsed_time += robot.delta_time_ms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void robot_handle_inputs_outputs(void)
|
void robot_update(void)
|
||||||
{
|
{
|
||||||
static bool led_state=false;
|
|
||||||
update_time();
|
update_time();
|
||||||
|
|
||||||
motors_update();
|
motors_update();
|
||||||
|
|
||||||
printf(">motor1_speed:%d\n", get_vitesse_moteur_1());
|
servos_update();
|
||||||
printf(">motor2_speed:%d\n", get_vitesse_moteur_2());
|
|
||||||
sleep_ms(200);
|
|
||||||
led_state= !led_state;
|
|
||||||
uint8_t data[] = {0x02, led_state};
|
|
||||||
int ret = i2c_write_blocking(i2c0, 0x09, data, 2, false);
|
|
||||||
|
|
||||||
//tight_loop_contents();
|
tight_loop_contents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void robot_deinit(void)
|
void robot_deinit(void)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include "headers/servos.h"
|
||||||
|
|
||||||
|
#include <hardware/pwm.h>
|
||||||
|
#include <pico/stdlib.h>
|
||||||
|
#include "headers/robot.h"
|
||||||
|
|
||||||
|
#define SERVO1_PWM_PIN 7
|
||||||
|
#define SERVO2_PWM_PIN 6
|
||||||
|
#define SERVO3_PWM_PIN 0
|
||||||
|
|
||||||
|
static inline uint get_servo_pwm_pin(servos_t servo)
|
||||||
|
{
|
||||||
|
switch(servo)
|
||||||
|
{
|
||||||
|
case SERVO1:
|
||||||
|
return SERVO1_PWM_PIN;
|
||||||
|
case SERVO2:
|
||||||
|
return SERVO2_PWM_PIN;
|
||||||
|
case SERVO3:
|
||||||
|
return SERVO3_PWM_PIN;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void servo_set_speed(servos_t servo, uint16_t pos)
|
||||||
|
{
|
||||||
|
const uint SERVO_PWM_PIN = get_servo_pwm_pin(servo);
|
||||||
|
pwm_set_gpio_level(SERVO_PWM_PIN, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void servos_init(void)
|
||||||
|
{
|
||||||
|
for(servos_t servo = SERVO1; servo < NB_SERVOS; servo++)
|
||||||
|
{
|
||||||
|
// Init PWM
|
||||||
|
const uint SERVO_PWM_PIN = get_servo_pwm_pin(servo);
|
||||||
|
|
||||||
|
const uint SLICE_NUM = pwm_gpio_to_slice_num(SERVO_PWM_PIN);
|
||||||
|
|
||||||
|
gpio_set_function(SERVO_PWM_PIN, GPIO_FUNC_PWM);
|
||||||
|
|
||||||
|
pwm_set_clkdiv(SLICE_NUM, 100);
|
||||||
|
pwm_set_wrap(SLICE_NUM, 25000);
|
||||||
|
|
||||||
|
pwm_set_enabled(SLICE_NUM, true);
|
||||||
|
|
||||||
|
servo_set_speed(servo, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void servos_update(void)
|
||||||
|
{
|
||||||
|
servo_set_speed(SERVO1, robot.i2c_buffer.buffer[I2C_BUFFER_SERVO1_ANGLE_H] << 8 | robot.i2c_buffer.buffer[I2C_BUFFER_SERVO1_ANGLE_L]);
|
||||||
|
servo_set_speed(SERVO2, robot.i2c_buffer.buffer[I2C_BUFFER_SERVO2_ANGLE_H] << 8 | robot.i2c_buffer.buffer[I2C_BUFFER_SERVO2_ANGLE_L]);
|
||||||
|
servo_set_speed(SERVO3, robot.i2c_buffer.buffer[I2C_BUFFER_SERVO3_ANGLE_H] << 8 | robot.i2c_buffer.buffer[I2C_BUFFER_SERVO3_ANGLE_L]);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue