Skip to content

Commit

Permalink
Merge pull request #1 from climate-action-kits/motorfix
Browse files Browse the repository at this point in the history
Moved DC control to cak-land.ts, fixed PWM(?) bug
  • Loading branch information
ross-inksmith authored Feb 6, 2023
2 parents 7cdadfd + 55d42cc commit 1074c9a
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 183 deletions.
43 changes: 39 additions & 4 deletions cak-land.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
//% weight=100 color=#421C52 icon="\uf1b9"
namespace cakLand {
export let M2_NEG: number = DigitalPin.P13
export let M2_POS: number = DigitalPin.P14
export let M1_NEG: number = DigitalPin.P15
export let M1_POS: number = DigitalPin.P16
// forward: Neg=1023, Pos=0; reverse: Neg=0,Pos=1023
let M2_NEG: AnalogPin = AnalogPin.P13
let M2_POS: AnalogPin = AnalogPin.P14
let M1_NEG: AnalogPin = AnalogPin.P15
let M1_POS: AnalogPin = AnalogPin.P16

export enum BoardSide {
//% block="left"
LEFT,
//% block="right"
RIGHT
}

function selectPins (side: BoardSide): AnalogPin[] {
let pos: AnalogPin, neg: AnalogPin;
// Climate Action Kits: M2 = Right; M1 = Left
switch (side) {
case BoardSide.LEFT:
neg = M1_NEG;
pos = M1_POS;
break;
case BoardSide.RIGHT:
neg = M2_NEG;
pos = M2_POS;
break;
}
return [pos, neg];
}

function percentToAnalog (percent: number): number {
return Math.map( Math.abs( percent ), 0, 100, 0, 1023);
}

export function powerMotor (side: BoardSide, power: number): void {
let [pos, neg] = selectPins(side);

pins.analogWritePin(neg, percentToAnalog(Math.max(power, 0)));
pins.analogWritePin(pos, percentToAnalog(Math.min(power, 0)));
}
}
62 changes: 12 additions & 50 deletions motor.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
/// <reference path="./cak-land.ts" />

//% weight=13 color=#ffd43a icon="" block="Motor"
namespace cakLandMotor {
enum Motor {
//% block="left"
LEFT = 0,
//% block="right"
RIGHT = 1
}

/**
*Turns the left motor at a specified speed
*/
//% block
//% blockId=motion_turn_left block="turn left motor at |speed: %speed"
//% speed.min=-100 speed.max=100
//% weight=60
export function turnLeft(speed: number): void {
drive(speed, 0);
}
//% block
//% blockId=motion_turn_left block="turn left motor at |speed: %speed"
//% speed.min=-100 speed.max=100
//% weight=60
export function turnLeft(speed: number): void {
cakLand.powerMotor(cakLand.BoardSide.LEFT, speed);
}

/**
*Turns the right motor at a specified speed
Expand All @@ -26,7 +21,7 @@ namespace cakLandMotor {
//% speed.min=-100 speed.max=100
//% weight=50
export function turnRight(speed: number): void {
drive(0, speed);
cakLand.powerMotor(cakLand.BoardSide.RIGHT, speed);
}

/**
Expand All @@ -50,40 +45,7 @@ namespace cakLandMotor {
//% rightWheelSpeed.min=-100 rightWheelSpeed.max=100
//% weight=40
export function drive(leftWheelSpeed: number, rightWheelSpeed: number): void {
motorControl(Motor.LEFT, leftWheelSpeed)
motorControl(Motor.RIGHT, rightWheelSpeed)
}

/**
* Advanced control of an individual motor. PWM is set to constant value.
*/
function motorControl(whichMotor: Motor, speed: number): void {
// Pick the motor using some magic values
let [pos, neg] = selectMotor(whichMotor);

// drive motors
let remappedSpeed = speed * 10;
// forward: power to neg, reverse: power to pos
pins.analogWritePin(neg, 1023 - Math.abs(Math.max(remappedSpeed, 0)));
pins.analogWritePin(pos, 1023 - Math.abs(Math.min(0, remappedSpeed)));
}

function selectMotor(whichMotor: Motor): AnalogPin[] {
let pos : AnalogPin, neg : AnalogPin;
switch (whichMotor) {
case Motor.LEFT:
pos = cakLand.M1_POS;
neg = cakLand.M1_NEG;
break;
case Motor.RIGHT:
pos = cakLand.M2_POS;
neg = cakLand.M2_NEG;
break;
default:
pos = cakLand.M1_POS;
neg = cakLand.M1_NEG;
break;
};
return [pos, neg];
turnLeft(leftWheelSpeed)
turnRight(rightWheelSpeed)
}
}
60 changes: 12 additions & 48 deletions pump.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,39 @@
/// <reference path="./cak-land.ts" />

//% weight=13 color=#01579b icon="" block="Pump"
namespace cakLandPump {
enum Pump {
//% block="left"
LEFT = 0,
//% block="right"
RIGHT = 1
}


/**
* Start the pump
*/
//% block
//% blockId=pump_start block="start %pump pump at speed %speed"
//% blockId=pump_start block="start %side pump at speed %speed"
//% speed.min=0 speed.max=100
//% weight=45
export function start(pump: Pump, speed: number): void {
pumpControl(pump, speed)
export function pumpStart(side: cakLand.BoardSide, speed: number): void {
cakLand.powerMotor(side, speed);
}

/**
* Stop the pump
*/
//% block
//% blockId=pump_stop block="stop %pump pump"
//% blockId=pump_stop block="stop %side pump"
//% weight=45
export function stop(pump: Pump): void {
pumpControl(pump, 0)
export function pumpStop(side: cakLand.BoardSide): void {
cakLand.powerMotor(side, 0);
}

/**
* Set a pump for a specified time at a specified speed.
*/
//% block
//% blockId=pump_duration block="run %pump pump at speed %speed for %duration seconds"
//% blockId=pump_duration block="run %side pump at speed %speed for %duration seconds"
//% duration.min=0 duration.max=10
//% speed.min=0 speed.max=100
//% weight=45
export function startDuration(pump: Pump, speed: number, duration: number): void {
start(pump, speed)
export function startDuration(side: cakLand.BoardSide, speed: number, duration: number): void {
pumpStart(side, speed)
basic.pause(duration*1000)
stop(pump)
}

/**
* Advanced control of an individual pump. PWM is set to constant value.
*/
function pumpControl(whichPump: Pump, speed: number): void {
let pumpSpeed: number

pumpSpeed = remapSpeed(speed)

if (whichPump == Pump.LEFT) {
pins.analogSetPeriod(cakLand.M1_NEG, 1024)
pins.analogWritePin(cakLand.M1_NEG, pumpSpeed)
} else {
pins.analogSetPeriod(cakLand.M2_NEG, 1024)
pins.analogWritePin(cakLand.M2_NEG, pumpSpeed)
}
}

// Rescale values from 0 - 100 to 0 - 1023
function remapSpeed(s: number): number {
let returnSpeed: number
if (s <= 0) {
returnSpeed = 0
} else if (s >= 100) {
returnSpeed = 1023
} else {
returnSpeed = (23200 + (s * 791)) / 100
}
return returnSpeed;
pumpStop(side)
}
}
145 changes: 64 additions & 81 deletions servo.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
/// <reference path="./cak-land.ts" />

//% weight=10 color=#ab47bc icon="" block="Servos"
namespace cakLandServos {
enum Position {
export enum Position {
//% block="up"
UP = 85,
//% block="half up"
HALF_UP = 40,
//% block="middle"
MIDDLE = 0,
//% block="half down"
HALF_DOWN = -40,
//% block="down"
DOWN = -85
//% block="half up"
HALF_UP = 40,
//% block="middle"
MIDDLE = 0,
//% block="half down"
HALF_DOWN = -40,
//% block="down"
DOWN = -85
}


Expand All @@ -22,84 +24,65 @@ namespace cakLandServos {
P12
}

export enum MotorPin{
//% block="left"
Left,
//% block="right"
Right
}

export enum Power {
//% block="off"
export enum motorPinSate {
Off = 0,
//% block="on"
On = 1,
On = 100
}

/**
* Enable a motor pin for access to 5v instead of the 3.3v on the rest of the breakout board
*/
//% block
//% blockId=servo_set_power block="turn %side motor + pin %state"
//% weight=100
export function motorPinPower (side: MotorPin, state: Power): void {
let pin : DigitalPin;
// Pick a pin
switch (side) {
case MotorPin.Left: pin = cakLand.M1_POS; break;
case MotorPin.Right: pin = cakLand.M2_POS; break;
default: pin = null; break;
}
if (pin) {
pins.digitalWritePin(pin, state);
}
}
/**
* Enable a motor pin for access to 5v instead of the 3.3v on the rest of the breakout board
*/
//% block
//% blockId=servo_set_power block="turn %side motor + pin %state"
//% weight=100
export function motorPinPower (side: cakLand.BoardSide, state: motorPinSate): void {
cakLand.powerMotor(side, state);
}

/**
* Function used to return actual AnalogPin from enum
*/
function getServoPin(pin: ServoPin): AnalogPin {
// Read from the pin specified from arg
switch (pin) {
case ServoPin.P0: return AnalogPin.P0;
case ServoPin.P1: return AnalogPin.P1;
case ServoPin.P2: return AnalogPin.P2;
case ServoPin.P8: return AnalogPin.P8;
case ServoPin.P12: return AnalogPin.P12;
default: AnalogPin.P0;
}
/**
* Function used to return actual AnalogPin from enum
*/
function getServoPin(pin: ServoPin): AnalogPin {
// Read from the pin specified from arg
switch (pin) {
case ServoPin.P0: return AnalogPin.P0;
case ServoPin.P1: return AnalogPin.P1;
case ServoPin.P2: return AnalogPin.P2;
case ServoPin.P8: return AnalogPin.P8;
case ServoPin.P12: return AnalogPin.P12;
}
}

/**
* Move specified servo to the selected position
*/
//% block
//% blockId=servo_set_pos block="set servo at %pin to |position: %position"
//% weight=60
export function setServoPosition(pin: ServoPin, position: Position) {
let n: number = position
pins.servoWritePin(getServoPin(pin), -n + 90)
}
/**
* Move specified servo to the selected position
*/
//% block
//% blockId=servo_set_pos block="set servo at %pin to |position: %position"
//% weight=60
export function setServoPosition(pin: ServoPin, position: Position) {
let n: number = position
pins.servoWritePin(getServoPin(pin), -n + 90)
}

/**
* Move specified servo back to home position
*/
//% block
//% blockId=servos_reset block="reset servo at %pin"
//% weight=40
export function resetServos(pin: ServoPin) {
pins.servoWritePin(getServoPin(pin), 90)
}
/**
* Move specified servo back to home position
*/
//% block
//% blockId=servos_reset block="reset servo at %pin"
//% weight=40
export function resetServos(pin: ServoPin) {
pins.servoWritePin(getServoPin(pin), 90)
}

/**
* Move specified servo to the given position in degrees.
* 0 is home, -90, 90 are the limits backward and forward
*/
//% block
//% blockId=servo_turn_degrees block="turn servo at %pin to |degrees: %degrees"
//% degrees.min=-90 degrees.max=90
//% weight=60
export function turnServo(pin: ServoPin, degrees: number) {
pins.servoWritePin(getServoPin(pin), -degrees + 90)
}
/**
* Move specified servo to the given position in degrees.
* 0 is home, -90, 90 are the limits backward and forward
*/
//% block
//% blockId=servo_turn_degrees block="turn servo at %pin to |degrees: %degrees"
//% degrees.min=-90 degrees.max=90
//% weight=60
export function turnServo(pin: ServoPin, degrees: number) {
pins.servoWritePin(getServoPin(pin), -degrees + 90)
}
}

0 comments on commit 1074c9a

Please sign in to comment.