HIDE NAV

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}