So here's a summary of the project:
The problem as we see it: A significant number of avid cyclists and would be cyclists don't ride as often as they might like, particularly in a 'utility' capacity, running errands, commuting, etc. Contributing factors include age, physical conditioning, persistent injuries, hilly terrain, and the distance or loads involved. This is unfortunate since this is the type of cycling that would have the most direct positive impact on congestion and fossil fuel consumption.
Power assisted bikes and kits have been on the market for a while now, and would appear to be a good solution to these problems except for one thing: they don't hold much appeal to experienced cyclists. Our research indicated several reasons for this, including bike quality, complexity, efficiency, ego, and the type of bike or bike fit.

We quickly realized that the best way to accomplish this was to keep the power assist as unobtrusive as possible so the interaction continued to be a 'cycling experience' and not a 'power assist experience'. This is were the power of the Arduino comes into play, allowing us to use an array of sensors to monitor ride conditions rather than requiring input from the rider via a throttle or switches. Since the rider no longer has to worry about monitoring and integrating the power assist with their ride, they are free to appreciate the cycling experience - without worrying about the big hill ahead!

Our algorithm begins by ensuring that the brake lever is not engaged using a momentary switch. If the brake is engaged, the boost is immediately turned off. The sketch then checks the rider position with a pressure sensor in the saddle, reducing the crank RPM if the rider is out of the saddle. The force exerted on the pedals is constantly monitored and sent to the central controller by a wireless data link.

Ideally, the assist provided to the crankset would reduce the force the rider exerts on the pedals and a state of equilibrium is reached between the rider and the assist. If the cyclist wishes to increase the cadence (crank rpm) a momentary increase in effort would cause the amount of boost to increase until equilibrium is again established. If the system is well set up, the rider would not be aware of these changes, focusing only on the ride.
Our Code: This is the code for the main controller using the VirtualWire library. While it compiles, we are not yet getting good data from the pedals and are still attempting to isolate the cause. The serial.print statements are included for debugging purposes.
#include <VirtualWire.h>
//Declair I/O Pins
const int assist_pin = A0;//threshhold
const int boost_pin = 9; //pwm out to mofset
const int pedalLeft_pin = 11;//left FSR via virtual_wire
const int pedalRight_pin = 12;//right FSR via virtual_wire
const int saddle_pin = A1;//saddle FSR
const int brake_pin = 8;//NC micro-switch on rear brake lever
const int transmit_en_pin = 3;
//Declair variables
int assist = 0; //amoount of desired assistance
int boost = 0; //PWM duty cycle 0-255
int pedalLeft = 0; //FSR value from left pedal
int pedalRight = 0; //FSR value from right pedal
int saddle = 0; //FSR value from saddle
int saddleOut = 0; //Threshold value for determing out of saddle
int standing = 30; //if the difference in pedal readings is below this value, assume the rider is jockeying
void setup() {
delay(500);
Serial.begin(9600); // Debugging only
Serial.println("setup");
vw_set_tx_pin( pedalRight_pin);
vw_set_rx_pin(pedalLeft_pin);
vw_set_ptt_pin(transmit_en_pin);
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
pinMode(boost_pin, OUTPUT); // set the boost_pin as output:
}
void loop() {
delay(2000);
int saddleFactor = 100; //default percentage for saddle corection
assist = analogRead(assist_pin); //read assist level
map(assist, 0, 1023, 0, 255);
saddle = analogRead(saddle_pin); //read saddle state
map(saddle, 0, 1023, 0, 255);
if (digitalRead(brake_pin) == HIGH) { //if the brake is off
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
vw_set_rx_pin(pedalLeft_pin); //set the recieve pin to left side
pedalLeft = vw_get_message(buf, &buflen);
vw_set_rx_pin(pedalRight_pin); //set the recieve pin to right side
pedalRight = vw_get_message(buf, &buflen);
if (pedalLeft > assist || pedalRight > assist) { //if either pedal exceedes the assist threshold
if (abs(pedalLeft - pedalRight) > standing) { //if the difference in pedal forces is greater than the standing test
if (saddle < saddleOut)saddleFactor = 80; //if rider is out of the saddle then seat = 0.80
boost = 180 * (pedalLeft + pedalRight) * (saddleFactor / 100) / assist;
analogWrite (boost_pin, boost);
}
}
}
Serial.print("Assist is set at ");
Serial.println(assist);
Serial.print("Brake is ");
Serial.println(brake_pin);
Serial.print("Left pedal is at ");
Serial.println(pedalLeft);
Serial.print("Right pedal is at ");
Serial.println(pedalRight);
Serial.print("Saddle is ");
Serial.println(saddle);
}


No bicycles were harmed in the making of Tailwind.
No comments:
Post a Comment