How to add a throttle to a Carrera Vengeance E Spec

Evian1040

Pedelecer
Jul 7, 2020
75
9
if you have access to a dual trace oscilloscope, then it will make the debugging process much easier by pinpointing where the problems are.
At the moment, I think we are still trying to make sure that the contact joins are 100% on Raj's board.
Do you have the same error 22 on startup?
Tonight i'll find out what the code does to my code.
 

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
yes, but we don't know where to look yet until you run the experiment.
We want to know if errors show up when you wire yellow wires together and green wires together outside the board.
 

Evian1040

Pedelecer
Jul 7, 2020
75
9
yes, but we don't know where to look yet until you run the experiment.
We want to know if errors show up when you wire yellow wires together and green wires together outside the board.
We will find out tonight
 

rajeshtailor

Pedelecer
Jun 5, 2020
170
3
So I have redone my connectors, and now the bike doesn't return any errors when I use my connectors and join the wires outside of the Arduino, so I am happy my cabling of the connectors is fine.

I retested v8 and v9 of the code and they still exhibit the same behaviours. v8 of the code is the closest we have to the finish line.
 

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
1. can you confirm what error you have on V8?
2. Do you have any error when joining just the green wires outside the board?
3. Do you have any error when joining just the yellow wires outside the board?
 

rajeshtailor

Pedelecer
Jun 5, 2020
170
3
1. can you confirm what error you have on V8?
2. Do you have any error when joining just the green wires outside the board?
3. Do you have any error when joining just the yellow wires outside the board?
For point 1.

v8 of the code doesn't return any errors on start up. Error 22 is received when you either stop throttling or stop pedalling.

For points 2 & 3 does it matter what version of the code I run on the Arduino?
 

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
version 8 or 9.
 

Evian1040

Pedelecer
Jul 7, 2020
75
9
Ok got the picoscope all set.
What readings should i get doing what?

EDIT: What code should i use to take the readings?
 
Last edited:

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
please check the voltage on pin A5 while running version 8 or 9 code.
If you use the throttle, the trace should move up/down with your throttle.
If it doesn't, like it's stuck on 4V, we will have to move the wire to pin D5 and change the line

const byte TorqueOutputPin = A5;
to
const byte TorqueOutputPin = 5;

and test again pin D5 and the throttle with the scope.
 
Last edited:

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
thank you or the traces. I will come back here after I analyse them.
 

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
Modified code, version 8.1

In this version, we move the controller's torque wire from A5 to D5.


Code:
// Version 8

const byte ThrottlePin = A0;
const byte CadenceInputPin = A2;
const byte TorqueInputPin = A3;
const byte TorqueOutputPin = 5;  // PWM 980Hz
const byte CadenceOutputPin = 13;
const byte TorqueAtRest = 198;

int pulseoff = 25; // milliseconds when D13 is low
int pulseon = 25;   // milliseconds when D13 is high 4Hz
int cadencepulselength = 991; // in milliseconds
bool cadencestate = false;
bool pulse = false;
unsigned long startMillis;
unsigned long currentMillis;

void setup() {
  pinMode(CadenceOutputPin, OUTPUT);
  pinMode(TorqueInputPin, INPUT);
  pinMode(TorqueOutputPin, OUTPUT); //ControllerTorquePin
  pinMode(CadenceInputPin, INPUT); //PASCadencePin
  digitalWrite(TorqueOutputPin, LOW);
  startMillis = millis();
  // Serial.begin(9600);
}

void loop() {
    if (millis()>currentMillis) // run once every millisecond
    {
        currentMillis = millis();
        // increment cadencepulselength
        if (cadencepulselength < 1000) cadencepulselength++;

        if (cadencestate)
        {
            // on cadencestate transtion from high to low, reset cadencepulselength
            if (analogRead(CadenceInputPin) < 512)
            {
               cadencepulselength = 0;
               cadencestate = false;
            }
        }
        if (analogRead(CadenceInputPin) > 512) cadencestate = true;

        // check throttle

        int torqueval = analogRead(ThrottlePin) / 4; // Read the value from the throttle pin A0
        if (torqueval < 75)  // disable throttle if voltage < 1.5V
        {
        // I'm pedalling
        int pastorque = analogRead(TorqueInputPin)/4; // torque input A3
        if (pastorque < 80) pastorque = 80;

        // replicate torque and cadence

        if (analogRead(CadenceInputPin) > 512)
        {
            digitalWrite(CadenceOutputPin, HIGH);
            // if I'm stopping for more than 1 second, set A5 to 3.8V to stop error 21
            if (cadencepulselength > 100) pastorque = TorqueAtRest;
            analogWrite(TorqueOutputPin, pastorque);
        }
        else
        {
            digitalWrite(CadenceOutputPin, LOW);
            pastorque = 0;
            // if I'm stopping for more than 1 second, set A5 to 3.5V to stop error 21
            if (cadencepulselength > 100) pastorque = TorqueAtRest;
            analogWrite(TorqueOutputPin, pastorque);  // sync pulse
        }
    }
    else
    {
        //I'm using the throttle
        cadencepulselength = 991; // fix throttle release
        pulse = true;
        if (currentMillis > (startMillis + pulseon)) pulse = false;
        if (currentMillis > (startMillis + pulseon + pulseoff)) startMillis = millis();     // reset timer clock
        if (pulse)  // SEND cadence and torque signal when D13 is high
        {
            digitalWrite(CadenceOutputPin, HIGH);
            analogWrite(TorqueOutputPin, torqueval);
        }
        else
        {
            digitalWrite(CadenceOutputPin, LOW);
            analogWrite(TorqueOutputPin, 0);  // sync pulse
        }
    }
  }
}

Hi Evian,

we need triggering to get a clean waveform.

on the Picoscope, can you set the following parameter:

Use Channel: A
horizontal axis: 50ms/div
vertical axis: 5V/div
triggering: simple edge, rising, threshold 1V, Channel A

PicoScope 6: Advanced Trigger Modes - YouTube
 

Evian1040

Pedelecer
Jul 7, 2020
75
9
Before i continue on the picoscope, woosh i just tested the code and we made big progress! I don't get error 21 or 22 on throttle at all!
 

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
that's excellent!
 

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
yes please. D5 and A3, the torque wires, throttle and pedals.
if you have a dual channel scope, you can hook D5 on channel A and A3 on channel B.

Have you still got errors with pedal mode?
 

Evian1040

Pedelecer
Jul 7, 2020
75
9
I can and did dual channel as requested with your other requirements.
Channel A is D5 and Channel B is A3 (singular tests were just on channel A)
I can't test the pedals for now but i can try tomorrow morning if i got spare time.

Anyways here is the other package:
Readings 1.1
 

Woosh

Trade Member
May 19, 2012
20,365
16,870
Southend on Sea
wooshbikes.co.uk
thank you Evian for the new readings.

Here is the revised version 9.1.
Torque output pin is moved to D5 as in version 8.1.

Code:
// Version 9.1
// use internal pullup resistors on input pins.
// implement low pass filter using recording and playback

const byte ThrottlePin = A0;
const byte CadenceInputPin = A2;
const byte TorqueInputPin = A3;
const byte TorqueOutputPin = 5; // D5 PWM 980Hz
const byte CadenceOutputPin = 13;

// I am on throttle
int pulseoff = 25; // milliseconds when D13 is low
int pulseon = 25;   // milliseconds when D13 is high 4Hz

// I am pedalling.
// I record the cadence pulse first.

bool cadencestate = false;
int cadencepulselength = 991;
int cadencepulseonlength = 0;
int cadencepulseofflength = 0;
unsigned long torqueontotal =0;
unsigned long torqueofftotal =0;

// then play it back, average values are used to implement low pass filter
int playbackpulseon = 25;
int playbackpulseoff = 25;
int playbacktorqueon = 0;
int playbacktorqueoff = 0;

bool pulse = false;
unsigned long startMillis;
unsigned long currentMillis;

void setup() {
    pinMode(CadenceOutputPin, OUTPUT);
    pinMode(TorqueInputPin, INPUT_PULLUP); // cadence input default high
    pinMode(TorqueOutputPin, OUTPUT); //ControllerTorquePin
    pinMode(CadenceInputPin, INPUT_PULLUP); //PASCadencePin
    digitalWrite(TorqueOutputPin, LOW);
    startMillis = millis();
    // Serial.begin(9600);
}

void loop() {
    if (millis()>currentMillis) // run once every millisecond
    {
        currentMillis = millis();

        // ****** Start recording current pulse ******
      
        if (cadencepulselength < 1000) cadencepulselength++;

        if (cadencestate)
        {
            // on cadencestate transtion from high to low, reset cadencepulselength and transfer accummulator to playback
            if (analogRead(CadenceInputPin) < 512)
            {
               cadencepulselength = 0;
               cadencestate = false;
               playbackpulseon = pulseonlength;
               playbackpulseoff = pulseofflength;
               if (pulseonlength >0) playbacktorqueon = torqueontotal/pulseonlength;
               if (pulseofflength >0) playbacktorqueoff = torqueofftotal/pulseofflength;
               torqueontotal = 0;
               torqueofftotal = 0;
               pulseonlength = 0;
               pulseofflength = 0;             
            }
            else // continue with pulse high
            {
                pulseonlength++;
                torqueontotal = torqueontotal + analogRead(torqueInputPin)/4;
            }
        }
        else // if cadencestate is low
        {
            if (analogRead(CadenceInputPin) < 512) // continue with pulse low
            {
                pulseofflength++;
                torqueofftotal = torqueofftotal + analogRead(torqueInputPin)/4;         
            }
        }
        if (analogRead(CadenceInputPin) > 512) cadencestate = true;
        if (cadencepulselength > 200) // defaults when stopping
        {
            cadencestate = true;
            torqueofftotal =0 ;
            torqueontotal =0;
          
        }
        // ****** end recording current pulse ******

        // check throttle

        int torqueval = analogRead(ThrottlePin) / 4; // Read the value from the throttle pin A0
        if (torqueval < 75)  // disable throttle if voltage < 1.5V
        {
            // ****** I'm pedalling, play back last pulse *****
          
            pulse = true;
            if (currentMillis > (startMillis + playbackpulseon)) pulse = false;
            if (currentMillis > (startMillis + playbackpulseon + playbackpulseoff)) startMillis = millis();     // reset timer clock
            if (pulse)
            {
                digitalWrite(CadenceOutputPin, HIGH);
                analogWrite(TorqueOutputPin, playbacktorqueon);
            }
            else
            {
                digitalWrite(CadenceOutputPin, LOW);
                analogWrite(TorqueOutputPin, playbacktorqueoff);
            }
            // ****** end play back last pulse *****
        }
        else
        {
            //I'm using the throttle
            analogWrite(TorqueOutputPin, torqueval);
            pulse = true;
            if (currentMillis > (startMillis + pulseon)) pulse = false;
            if (currentMillis > (startMillis + pulseon + pulseoff)) startMillis = millis();     // reset timer clock
            if (pulse)  digitalWrite(CadenceOutputPin, HIGH);
            else digitalWrite(CadenceOutputPin, LOW);
        }
    }
}
 

Advertisers