I2C Control of a Pi-Pico from a Raspberry Pi
A demonstration of SDL Game Library GameController input mapping to a servo and pwm based LED dimmer as a throttle.
main.c
#include <SDL.h>
#include <lgpio.h>
#include <stdio.h>
#define LED_GP 18
#define SERVO_GP 17
#define AXIS_MAX 32767
//Global vars
//pwm frequency is maximum 10kHz
int pwm_freq = 10000;
//if cycles set to 0 pwm will loop endlessly
int pwm_cycles_infinte = 0;
int n_cycles = 4;
int chip_handle;
double loop_delay_sec = .01;
int servo_pw_max = 2500;
int servo_pw_center = 1500;
int servo_pw_min = 500;
int servo_frequency = 50;
int servo_offset = 0;
int servo_cycles = 0;
int main(){
//initialize lgpio services
chip_handle = lgGpiochipOpen(0);
if(chip_handle < 0) {
puts("Error in initialization, handle is negative");
return 0;
}
lgGpioClaimOutput(chip_handle, LG_SET_PULL_UP, SERVO_GP, 0);
lgGpioClaimOutput(chip_handle, LG_SET_PULL_NONE, LED_GP, 0);
//initialize SDL game library and setup for game controller input only
if( SDL_Init(SDL_INIT_GAMECONTROLLER) < 0 ){
puts("SDL initialization failed");
} else {
puts("SDL_Init success");
}
if(SDL_NumJoysticks() <= 0) {
puts("No joysticks detected. Quitting...");
return 0;
}
SDL_GameController* controller = SDL_GameControllerOpen(0);
if(controller == NULL) {
puts("Error opening game controller 0. Quitting...");
return 0;
}
puts("Game Controller Setup Complete.\n \t To Quit, Press Button 0 [South Button].");
//Primary Control Loop: SDL event handling of game controller
while(1) {
SDL_Event event;
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT: puts("Quitting..."); SDL_Quit(); return 0; break;
case SDL_CONTROLLERAXISMOTION:
int axis_no = event.caxis.axis;
int axis_value = event.caxis.value;
float axis_fraction = (float)event.caxis.value / AXIS_MAX;
if(axis_no == 0){
//left stick x-axis
int servo_pw_scale = servo_pw_max - servo_pw_center;
int servo_pw = (int)(axis_fraction * servo_pw_scale) + servo_pw_center;
lgTxServo(chip_handle, SERVO_GP, servo_pw, servo_frequency, servo_offset, servo_cycles);
} else if(axis_no == 3){
//right stick y
float duty = axis_fraction * 100.0f * -1.0f; //-1 multiplier to reverse it
lgTxPwm(chip_handle, LED_GP, pwm_freq, duty, 0, pwm_cycles_infinte);
}
break;
case SDL_CONTROLLERBUTTONDOWN:
//button 0 quits
int button_dn_no = event.cbutton.button;
if(button_dn_no == 0){
puts("button 0 pressed, exiting");
SDL_Quit();
return(0);
}
break;
case SDL_CONTROLLERBUTTONUP:
//no actions for button release
break;
}
}
lguSleep(loop_delay_sec);
}
return 0;
}
makefile
CC = gcc
PNAME = sdl-gamecon-servo-led-dim
SRCS = $(wildcard src/*.c)
LINKS = -lrt -I/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -llgpio
build:
${CC} -o bin/${PNAME} ${SRCS} ${LINKS}
run:
@bin/${PNAME}