An Electric Scooter Community on a Mission to Stamp out Transportation Mediocrity.

Changing mobility one trip at a time.
#18177
XFX wrote:
Tue Dec 10, 2019 9:35 am
Hey from germany! I i check your 0.2 Firmware and i think i found the speed limiter! Is this a read from the original controller?
You think you found the speed controller? How so? Can you provide more details. I am very interested in getting my scooter unlocked and above the lame 20kph (12mph) speed limit.
#18179
Biingobom wrote:
Mon Dec 16, 2019 3:42 am
Does anyone have an idea where I can buy a cheap charger for a JUMP or TIER (OKAI ES200)? Ideally with the right plug...
I have.a pair of jump scooters that are ES200B and one scooter that is a Jump Segway Ninebot ES4. All three scooters work great with this charger that I bought off Amazon for $13.99. I think it is 42v 2a

https://www.amazon.com/gp/product/B07WN ... UTF8&psc=1
Last edited by bigredrobot on Mon Dec 16, 2019 1:43 pm, edited 1 time in total.
#18180
electricool wrote:
Mon Dec 16, 2019 3:38 am
hi why don't you look like that, i didn't find a smaller one :)
it takes 40v easy

https://www.banggood.com/fr/5V-36V-to-5 ... rehouse=CN
If I hadn't already purchased my options I would definitely try one out. It seems too small to be true. I think the real problem, and I should preface this with I am not a mechanical or electrical engineer) is multifaceted:
  • The efficiency is best when the input and out put are as close as possible, so taking the max allowable input and tuning it down to what is very close to the lowest possible value reduces efficiency. Most of these devices are rated 92%-97% but when people have tested it they are seeing closer to 60%. That inefficiency goes into heat and for my application where I want to put it into a box where it could get hot, not great.
  • Poor build quality. Many that I've seen are off brand and people regularly report ordering 5 or 10 and having 80% fail rate.
  • There is no margin of error. I've read scooter voltage is 36-42v. I've seen 36v-37v depending on state of charge in battery. When the max voltage is 36v, it seems possible to over tax.
  • Almost all of these state they may have a max of 40v but for running above 1-2amps for any significant amount of working time requires ventilation and heat sink.
  • The voltage rating on capacitors seems relevant. Some of the 35-40v input devices I've seen have a 35v written on the capacitors. Other's of the same rating have a 50v rating on capacitor.
  • Some devices do not hold on to the output settings after long periods of no power. Thus, if you put this setup in a box and give a scooter to friend or family member, they let the battery die completely, when they charge the scooter and power up the unlock sequence through Arduino, the voltage regulator will reset to just pass the original voltage -1.5v volts. An Arduino would be exposed to 34v inside a box and fry out.
I am working on a project to help an impound unlock some devices so brittleness is a real concern. Based on all this, it seems smart to find a step down that can handle 48v-60v, set it up to step down from 36v to 5v. The epoxy filled versions with a set 5v2a output with out the option to change seem like a good place to start. They're built for the marine/auto industries so designed to shove in a box and forgotten.
#18181
Hi all,

I pimped up a bit the source code to have some more functionalities :
- Scooter keeps turned on.
- Light can be turned on and off by adding a toggle switch to the arduino (press switch can be easily implemented).
- Scooter is locked and wheels blocked when power is cut on arduino. The code will detect input power going down and will send lock code before dying. Really handy !

How to cable it :
- Red and black wire from scooter goes to step down buck converter. Add a simple toggle switch on the 42v+ line to be able to cut power to the Arduino.
- Add another toggle switch between 5v on Arduino to A0.
- Connect RX and TX as explained before.
- Connect blue cable to the D2 on Arduino.

Everything has been tested (I don't know the model), speed is very good and acceleration also ! Will try on other models if possible.

Evolutions :
- More fluid startup, for now the scooter try hardly to start and succeed after some times
- Unlock speed (need somebody to find the hex code to send :)
- Boost acceleration (if possible ?)
- Bluetooth lock / unlock
- Any idea ?

Here is the source code, explained so everybody can add or modify code easily :
Please share !
Code: Select all
#include <Arduino.h>

// ------------------------------------------------------------------------------------------- SETTINGS

// Digital output which send voltage to the brain
int powerPin = 2;

// Analog pin where is connected the light switch
int lightSwitchPin = 0;

// Threshold to detect shutdown and send lock command before turning off (in mV)
int vinShutdownVoltage = 3600;

// Voltage to consider a switch on for the light (in V)
int lightOnVoltage = 2;

// ------------------------------------------------------------------------------------------- HELPERS

/**
 * Read VIN voltage
 */
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}

/**
 * Quick blink of the internal LED
 */
void blink ()
{
  for (int i = 0; i < 8; i ++)
  {
    delay( 40 );
    digitalWrite(LED_BUILTIN, (i % 2 == 0) ? HIGH : LOW);
  }
}

// ------------------------------------------------------------------------------------------- COMMANDS
// Commands sent to the brain

void sendStartCommand ()
{
  byte command[] = {0xA6, 0x12, 0x02, 0x11, 0x14, 0x0B};
  Serial.write( command , sizeof(command) );
}
void sendLightCommand ()
{
  byte command[] = {0xA6, 0x12, 0x02, 0x15, 0x14, 0x30};
  Serial.write( command , sizeof(command) );
}
void sendStopCommand ()
{
  byte command[] = {0xA6, 0x12, 0x02, 0x10, 0x14, 0xCF};
  Serial.write( command , sizeof(command) );
}

// ------------------------------------------------------------------------------------------- SETUP LIFECYCLE

// Counter for each loop to send commands with smaller delays
int stepCounter = -1;

// Counter to allow shutdown only after everything is up
int allowShutdownCounter = 0;

// Light state (true is on)
bool lightState = false;


void setup()
{
  // We speak serial with the brain
  Serial.begin( 9600 );

  // Configure IO
  pinMode( LED_BUILTIN, OUTPUT );

  // Enable digital pin to talk to the brain
  pinMode(powerPin, OUTPUT);
  digitalWrite(powerPin, HIGH);

  // Start
  sendStartCommand();
  delay(100);
  blink();
}

// ------------------------------------------------------------------------------------------- LOOP LIFECYCLE

void loop ()
{
  // --- Light state and repeat to keep alive
  
  // Counter to allow faster turn off state
  stepCounter ++;
  
  // Read analog value for light switch
  int lightLevel = analogRead( lightSwitchPin );
  float lightVoltage = lightLevel * (5.0 / 1024.0);

  // Convert voltage to boolean, is light switch on ?
  bool newLightState = ( lightVoltage > lightOnVoltage );

  // If light switch state is different than light state
  // Or if we elapsed some time
  if (
      // This is to avoid flooding and only send when state changes
      ( newLightState != lightState && stepCounter >= 50 )
      
      // This is because we need to send last command to avoid the brain to sleep
      || stepCounter >= 500

      // First init of light state
      || stepCounter == -1
  ) {
    // Reset step counter and update light state
    stepCounter = 0;
    lightState = newLightState;
    
    // If voltage is near 5V, turn on light and start the engine
    lightState ? sendLightCommand()
    
    // Otherwise, just start the engine and keep it on
    : sendStartCommand();
  }

  // --- Shutdown detection

  // Set a counter to allow shutdown. This is to avoid shutdown detection at startup
  if ( allowShutdownCounter < 200 ) allowShutdownCounter ++;
  
  // Read VIN value and if voltage is droping
  while ( readVcc() < vinShutdownVoltage && allowShutdownCounter >= 200 )
  {
    // We tell the brain to stop
    sendStopCommand();
    digitalWrite(powerPin, LOW);

    // Blink until death
    while (true) blink();
  }

  // --- Repeat

  // Wait a bit to avoid flooding the brain
  // With this low delay we can detect voltage drop in VIN and lock before we turned off
  // +2ms in readVcc()
  delay( 3 ); // 5ms
}
#18194
Sweet Code Zou,
A couple of things I wrote a little code using an app that works for Android and iOS called RemoteXY. I use it to tell an ESP32 to turn the scooter on and off. Its available here on https://hackaday.io/project/168667-elec ... r-teardown Im sure it can be converted over to whatever your needs are. Second Im working on a little bit of code to test all the possible commands available. I have a whole bunch of commands in Hex but I have no idea what most of the do. The scooter test rig Ive got does a whole lot of blinking but I need to move on to a moving scooter to discover what they do. Ive seen something in the order of two dozen new commands that do something. But the scooter doesn't give a whole lot of feed back on what its doing inside. That is also listed on my lackaday page. If your interested in riding around on a scooter with a laptop in hand please do.

Zou wrote:
Mon Dec 16, 2019 1:59 pm
Hi all,

I pimped up a bit the source code to have some more functionalities :
- Scooter keeps turned on.
- Light can be turned on and off by adding a toggle switch to the arduino (press switch can be easily implemented).
- Scooter is locked and wheels blocked when power is cut on arduino. The code will detect input power going down and will send lock code before dying. Really handy !

How to cable it :
- Red and black wire from scooter goes to step down buck converter. Add a simple toggle switch on the 42v+ line to be able to cut power to the Arduino.
- Add another toggle switch between 5v on Arduino to A0.
- Connect RX and TX as explained before.
- Connect blue cable to the D2 on Arduino.

Everything has been tested (I don't know the model), speed is very good and acceleration also ! Will try on other models if possible.

Evolutions :
- More fluid startup, for now the scooter try hardly to start and succeed after some times
- Unlock speed (need somebody to find the hex code to send :)
- Boost acceleration (if possible ?)
- Bluetooth lock / unlock
- Any idea ?

Here is the source code, explained so everybody can add or modify code easily :
Please share !
Code: Select all
#include <Arduino.h>

// ------------------------------------------------------------------------------------------- SETTINGS

// Digital output which send voltage to the brain
int powerPin = 2;

// Analog pin where is connected the light switch
int lightSwitchPin = 0;

// Threshold to detect shutdown and send lock command before turning off (in mV)
int vinShutdownVoltage = 3600;

// Voltage to consider a switch on for the light (in V)
int lightOnVoltage = 2;

// ------------------------------------------------------------------------------------------- HELPERS

/**
 * Read VIN voltage
 */
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}

/**
 * Quick blink of the internal LED
 */
void blink ()
{
  for (int i = 0; i < 8; i ++)
  {
    delay( 40 );
    digitalWrite(LED_BUILTIN, (i % 2 == 0) ? HIGH : LOW);
  }
}

// ------------------------------------------------------------------------------------------- COMMANDS
// Commands sent to the brain

void sendStartCommand ()
{
  byte command[] = {0xA6, 0x12, 0x02, 0x11, 0x14, 0x0B};
  Serial.write( command , sizeof(command) );
}
void sendLightCommand ()
{
  byte command[] = {0xA6, 0x12, 0x02, 0x15, 0x14, 0x30};
  Serial.write( command , sizeof(command) );
}
void sendStopCommand ()
{
  byte command[] = {0xA6, 0x12, 0x02, 0x10, 0x14, 0xCF};
  Serial.write( command , sizeof(command) );
}

// ------------------------------------------------------------------------------------------- SETUP LIFECYCLE

// Counter for each loop to send commands with smaller delays
int stepCounter = -1;

// Counter to allow shutdown only after everything is up
int allowShutdownCounter = 0;

// Light state (true is on)
bool lightState = false;


void setup()
{
  // We speak serial with the brain
  Serial.begin( 9600 );

  // Configure IO
  pinMode( LED_BUILTIN, OUTPUT );

  // Enable digital pin to talk to the brain
  pinMode(powerPin, OUTPUT);
  digitalWrite(powerPin, HIGH);

  // Start
  sendStartCommand();
  delay(100);
  blink();
}

// ------------------------------------------------------------------------------------------- LOOP LIFECYCLE

void loop ()
{
  // --- Light state and repeat to keep alive
  
  // Counter to allow faster turn off state
  stepCounter ++;
  
  // Read analog value for light switch
  int lightLevel = analogRead( lightSwitchPin );
  float lightVoltage = lightLevel * (5.0 / 1024.0);

  // Convert voltage to boolean, is light switch on ?
  bool newLightState = ( lightVoltage > lightOnVoltage );

  // If light switch state is different than light state
  // Or if we elapsed some time
  if (
      // This is to avoid flooding and only send when state changes
      ( newLightState != lightState && stepCounter >= 50 )
      
      // This is because we need to send last command to avoid the brain to sleep
      || stepCounter >= 500

      // First init of light state
      || stepCounter == -1
  ) {
    // Reset step counter and update light state
    stepCounter = 0;
    lightState = newLightState;
    
    // If voltage is near 5V, turn on light and start the engine
    lightState ? sendLightCommand()
    
    // Otherwise, just start the engine and keep it on
    : sendStartCommand();
  }

  // --- Shutdown detection

  // Set a counter to allow shutdown. This is to avoid shutdown detection at startup
  if ( allowShutdownCounter < 200 ) allowShutdownCounter ++;
  
  // Read VIN value and if voltage is droping
  while ( readVcc() < vinShutdownVoltage && allowShutdownCounter >= 200 )
  {
    // We tell the brain to stop
    sendStopCommand();
    digitalWrite(powerPin, LOW);

    // Blink until death
    while (true) blink();
  }

  // --- Repeat

  // Wait a bit to avoid flooding the brain
  // With this low delay we can detect voltage drop in VIN and lock before we turned off
  // +2ms in readVcc()
  delay( 3 ); // 5ms
}
#18195
Hey a little teaser command I found that this one makes the scooter blink the headlight and cause the MPH on the LCD flash. If anyone if will to test it out there are dozens of these commands. That I have no idea what they do other than flashing the headlight. I think that is like a command acknowledged sort of thing.
0xA6 ,0x12 ,0x2 ,0xEF ,0x14 ,0x4E Flashes headlight and MPH
0xA6 ,0x12 ,0x2 ,0xFF ,0x14 ,0xA2 Only flashes headlight
#18197
Hey Guys,

You all made GREAT Success!!!

I'm glad that I've shared my Solution.

@MrSpriggs1 Wonderfull work! :) I will take an look and try the next days some of your commands on the street. I will make me an script which will enable the scooter and then send one string after another.. How or where you found all these commands?
@Zou Perfect! Keep on working on it... :)

I've made progress by unlocking/locking via nfc, I wired everything and the Hardware works... But I've struggled with the software I came on an point where I wasn't able to go on anymore by myself... but no problem, i've took my brother and he succeeded with the coding. We have now some smaller bugs left but then I can try and make our solution public again...
#18198
Hey Basti,
The other day a guy named John Lee, helped me break the formula for making commands. He linked me to a Lime Scooter group. Where they figured out how to send commands to their own scooters. Reading their information show me the data structure of a packet being sent and the CRC at the end of the data. So when I reversed the three known packets in a CRC calculator it showed me which CRC this scooter uses. Which is CRC-8 Maxim for all you reading at home.
When I put it all together, it all worked perfectly. So Now I have a formula for making the CRC (i.e. checksum) And that opened up a way to send any possible command. So in reality there are 255 possible commands. A huge number of these commands make the headlight blink. And Im sure an even bigger number don't do anything at all. In that data is all the possible answers to anything we might be able to make the scooter do. i.e. Speed it up, lock it down, flash the headlight in the day. clone RICK Sanchez.
You can follow what Ive been doing on https://hackaday.io/project/168667-elec ... r-teardown
#18200
MrSpriggs1 wrote:
Tue Dec 17, 2019 8:15 am
Hey Basti,
The other day a guy named John Lee, helped me break the formula for making commands. He linked me to a Lime Scooter group. Where they figured out how to send commands to their own scooters. Reading their information show me the data structure of a packet being sent and the CRC at the end of the data. So when I reversed the three known packets in a CRC....
Yeah, i've read your poost on hackaday after my post... It took his time but I will try to make it to my "Byte send" script. I should be able by using an tablet to get through every command....
I will include the fastcrc in my script and will let you all kjnow my results...
  • 1
  • 11
  • 12
  • 13
  • 14
  • 15
  • 80

As this was a rental version whos overstock was […]

Any one got any info on beryl bikes I seen a few[…]

LH/ TF-100 Style Display.

Hi I recently converted a Bird Zero to a personal […]

How do you operate dash without button? I have[…]