Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions coresdk/src/backend/gpio_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,20 @@ namespace splashkit_lib
}
}
}

int sk_get_pwm_range(int pin)
{
if (check_pi())
{
int result = get_PWM_range(pi, pin);
if (result < 0)
{
LOG(ERROR) << sk_gpio_error_message(result);
}
return result;
}
}

void sk_set_pwm_frequency(int pin, int frequency)
{
if (check_pi())
Expand Down
1 change: 1 addition & 0 deletions coresdk/src/backend/gpio_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ namespace splashkit_lib
void sk_gpio_set_pull_up_down(int pin, int pud);
void sk_gpio_write(int pin, int value);
void sk_set_pwm_range(int pin, int range);
void sk_get_pwm_range(int pin);
void sk_set_pwm_frequency(int pin, int frequency);
void sk_set_pwm_dutycycle(int pin, int dutycycle);
void sk_gpio_clear_bank_1();
Expand Down
60 changes: 25 additions & 35 deletions coresdk/src/coresdk/raspi_gpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,21 @@ namespace splashkit_lib
#endif
}

int raspi_get_pwm_range(gpio_pin pin)
{
#ifdef RASPBERRY_PI
int bcmPin = boardToBCM(pin);
if (bcmPin >= 2)
{
return sk_get_pwm_range(bcmPin);
}
return -1;
#else
LOG(ERROR) << "Unable to get PWM range - GPIO not supported on this platform";
return -1;
#endif
}

void raspi_set_pwm_frequency(gpio_pin pin, int frequency)
{
#ifdef RASPBERRY_PI
Expand Down Expand Up @@ -242,58 +257,33 @@ namespace splashkit_lib
return "";
#endif
}

int raspi_get_servo_pulsewidth(gpio_pin pin)
{
#ifdef RASPBERRY_PI
if (has_gpio())
int bcmPin = boardToBCM(pin);
// if the pin is not a PWM pin, return
if (bcmPin >= 2)
{
gpio_pin pwmPins[] = {PIN_12, PIN_32, PIN_33, PIN_35};
// if the pin is not a PWM pin, return
if (std::find(std::begin(pwmPins), std::end(pwmPins), pin) == std::end(pwmPins))
{
LOG(ERROR) << "Pin " << pin << " is not a PWM pin";
return -1;
}
int bcmPin = boardToBCM(pin);
// if the pin is not a PWM pin, return
if (bcmPin < 2)
{
LOG(ERROR) << "Pin " << pin << " is not a PWM pin";
return -1;
}
return sk_get_servo_pulsewidth(bcmPin);
}
else
{
LOG(ERROR) << "Servo driver not supported on this platform";
return -1;
}
return -1;
#else
LOG(ERROR) << "Servo driver not supported on this platform";
LOG(ERROR) << "Unable to get servo pulse width - GPIO not supported on this platform";
return -1;
#endif
}

void raspi_set_servo_pulsewidth(gpio_pin pin, int pulsewidth)
{
#ifdef RASPBERRY_PI
if (has_gpio())
int bcmPin = boardToBCM(pin);
if (bcmPin >= 2)
{
gpio_pin pwmPins[] = {PIN_12, PIN_32, PIN_33, PIN_35};
// if the pin is not a PWM pin, return
if (std::find(std::begin(pwmPins), std::end(pwmPins), pin) == std::end(pwmPins))
{
LOG(ERROR) << "Pin " << pin << " is not a PWM pin";
return; // ← early return so we don’t drive an unsupported pin
}
int bcmPin = boardToBCM(pin);
sk_set_servo_pulsewidth(bcmPin, pulsewidth);
}
else
{
LOG(ERROR) << "Servo driver not supported on this platform";
}
#else
LOG(ERROR) << "Servo driver not supported on this platform";
LOG(ERROR) << "Unable to set servo pulse width - GPIO not supported on this platform";
#endif
}

Expand Down
10 changes: 10 additions & 0 deletions coresdk/src/coresdk/raspi_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ namespace splashkit_lib
*/
void raspi_set_pwm_range(gpio_pin pin, int range);

/**
* @brief Gets the PWM range for the specified pin.
*
* This function gets the PWM range for the specified pin.
*
* @param pin The pin to get the PWM range for.
* @returns The PWM range of the pin.
*/
int raspi_get_pwm_range(gpio_pin pin);

/**
* @brief Sets the PWM frequency for the specified pin.
*
Expand Down
24 changes: 18 additions & 6 deletions coresdk/src/coresdk/raspi_motor_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ namespace splashkit_lib
if (!dev || dev->id != MOTOR_DRIVER_PTR)
return;
// input speed goes from 0 to 1
// output speed goes from 0 to 255
int pwm_speed = static_cast<int>(speed * 255);
// scale to EN pin's PWM range
int pwm_range = raspi_get_pwm_range(dev->en);
int pwm_speed = static_cast<int>(speed * pwm_range);
if (speed < 0)
{
speed = 0;
Expand All @@ -114,14 +115,25 @@ namespace splashkit_lib
#endif
}

void stop_motor(motor_device dev)
void brake_motor(motor_device dev)
{
#ifdef RASPBERRY_PI
#ifdef RAPSBERRY_PI
if (!dev || dev->id != MOTOR_DRIVER_PTR)
return;
// Brake: both inputs high
// L298N goes into brake mode when the two inputs are equal
raspi_write(dev->in1, GPIO_HIGH);
raspi_write(dev->in2, GPIO_HIGH);
#else
LOG(ERROR) << "motor driver not supported on this platform";
#endif
}

void stop_motor(motor_device dev)
{
#ifdef RASPBERRY_PI
if (!dev || dev->id != MOTOR_DRIVER_PTR)
return;
// L298N goes into coast mode when EN = LOW
raspi_set_pwm_dutycycle(dev->en, GPIO_LOW);
#else
LOG(ERROR) << "Motor driver not supported on this platform";
Expand All @@ -135,7 +147,7 @@ namespace splashkit_lib
return;
raspi_write(dev->in1, GPIO_LOW);
raspi_write(dev->in2, GPIO_LOW);
raspi_set_pwm_dutycycle(dev->en, GPIO_LOW);
raspi_set_pwm_dutycycle(dev->en, GPIO_LOW)
_motor_devices.erase(dev->name);
delete dev;
#else
Expand Down
12 changes: 7 additions & 5 deletions coresdk/src/coresdk/raspi_motor_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include <string>
#include <map>
#include "backend_types.h" // for pointer_identifier
#include "backend_types.h" // for pointer_identifier
#include "easylogging++.h"
#include "types.h"

Expand Down Expand Up @@ -42,14 +42,11 @@
* @attribute class motor_device
*/
namespace splashkit_lib {

/**
* @brief Opaque handle for an L298N motor driver instance.
*/
typedef struct _motor_data *motor_device;



/**
* Checks if a motor device with the given name is already opened.
* @param name Identifier for the motor driver.
Expand Down Expand Up @@ -93,6 +90,12 @@ namespace splashkit_lib {
* Stops the motor immediately (brake).
* @param dev The motor device handle.
*/
void brake_motor(motor_device dev);

/**
* Stops the motor and allows it to coast to a stop.
* @param dev The motor device handle.
*/
void stop_motor(motor_device dev);

/**
Expand All @@ -111,7 +114,6 @@ namespace splashkit_lib {
* Closes all opened motor devices.
*/
void close_all_motors();

}

#endif // RASPI_MOTOR_DRIVER_H
39 changes: 30 additions & 9 deletions coresdk/src/coresdk/raspi_servo_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ namespace splashkit_lib
pointer_identifier id;
std::string name;
gpio_pin pin;
double min_angle, max_angle;
};

static std::map<std::string, servo_device> _servo_devices;
static const unsigned MIN_PW = 500; // µs at 0°
static const unsigned MAX_PW = 2500; // µs at 180°
// Pulse widths for the min and max values of servo range
static const unsigned MIN_PW = 500;
static const unsigned MAX_PW = 2500;

bool has_servo_device(const std::string &name)
{
Expand All @@ -35,7 +37,7 @@ namespace splashkit_lib
return (it != _servo_devices.end()) ? it->second : nullptr;
}

servo_device open_servo(const std::string &name, gpio_pin control_pin)
servo_device open_servo(const std::string &name, gpio_pin control_pin, double min_angle, double max_angle)
{
#ifdef RASPBERRY_PI
if (has_servo_device(name))
Expand All @@ -45,9 +47,11 @@ namespace splashkit_lib
raspi_init();

auto dev = new _servo_data();
dev->id = SERVO_DRIVER_PTR; // you'll need to #define this in backend_types.h
dev->id = SERVO_DRIVER_PTR; // defined SERVO_DRIVER_PTR in backend_types.h
dev->name = name;
dev->pin = control_pin;
dev->min_angle = min_angle;
dev->max_angle = max_angle;

// configure as output
raspi_set_mode(control_pin, GPIO_OUTPUT);
Expand All @@ -65,17 +69,34 @@ namespace splashkit_lib
#endif
}

void set_servo_value(servo_device dev, double value)
{
#ifdef RASPBERRY_PI
if (!dev || dev->id != SERVO_DRIVER_PTR)
return;

// input value is 0..1
// scale to servo pulse width range
unsigned pw = static_cast<unsigned>(value * (MAX_PW - MIN_PW) + MIN_PW);
raspi_set_servo_pulsewidth(dev->pin, pw);
#else
LOG(ERROR) << "Servo driver not supported on this platform";
#endif
}

void set_servo_angle(servo_device dev, double angle)
{
#ifdef RASPBERRY_PI
if (!dev || dev->id != SERVO_DRIVER_PTR)
return;

// clamp to [0,180]
angle = std::clamp(angle, 0.0, 180.0);
unsigned pw = static_cast<unsigned>(
MIN_PW + (angle / 180.0) * (MAX_PW - MIN_PW));
// raspi_set_pwm_dutycycle(dev->pin, pw);
double min = dev->min_angle;
double max = dev->max_angle;

// clamp input to servo range
angle = std::clamp(angle, min, max);
// scale angle to pulse width range
unsigned pw = static_cast<unsigned>((angle - min / max - min) * (MAX_PW - MIN_PW) + MIN_PW);
raspi_set_servo_pulsewidth(dev->pin, pw);
#else
LOG(ERROR) << "Servo driver not supported on this platform";
Expand Down
12 changes: 11 additions & 1 deletion coresdk/src/coresdk/raspi_servo_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,20 @@ namespace splashkit_lib
* Open (and initialize) a servo on the given board pin.
* @param name Your identifier for this servo.
* @param control_pin Board‐numbered GPIO pin for the servo signal line.
* @param min_angle The minimum angle of this servo in degrees, defaults to 0.
* @param max_angle The maximum angle of this servo in degrees, defaults to 180.
* @returns A valid servo_device, or nullptr on failure.
*/
servo_device open_servo(const std::string &name, gpio_pin control_pin);
servo_device open_servo(const std::string &name, gpio_pin control_pin, double min_angle = 0, double max_angle = 180);

/**
* Maps 0..1 to the pulse width range of a servo.
* Useful if someone doesn't know the min and max angle of a servo device.
* @param dev The servo device to control.
* @param value The value, from 0 (min) to 1 (max) to set the servo to.
*/
void set_servo_value(servo_device dev, double value);

/**
* Convenience: map an angle (0…180°) into the 500…2500 µs range.
* This is a linear mapping, so it may not be accurate for all servos.
Expand Down
4 changes: 2 additions & 2 deletions coresdk/src/test/test_raspi_servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void run_servo_driver_tests()

// Pause until user is ready
write_line("Press ENTER to begin...\n");
read_line(); // splashkit’s line-reader :contentReference[oaicite:0]{index=0}
read_line(); // splashkit’s line-reader

// Open the servo on board pin 12
servo_device srv = open_servo("TestServo", PIN_12);
Expand All @@ -44,7 +44,7 @@ void run_servo_driver_tests()
for (int deg = 0; deg <= 180; deg += STEP_DEG)
{
set_servo_angle(srv, deg);
delay(DELAY_MS); // splashkit’s millisecond delay :contentReference[oaicite:1]{index=1}
delay(DELAY_MS); // splashkit’s millisecond delay
}

// Hold at 180° for a second
Expand Down
Loading