Help me fix my wheelchair with Arduino Nano

Hello!

I recently bought a used mobility scooter but didn't last too long. Brushes were gone. I bought a damaged hoverboard and planning on using the motors, but don't have any controllers. I made a schematic but i can't find any software that will work with my setup. Can you please help me?

Here's the schematic i've made from a couple other schematics:

Thank you very much!

What do you want the software to do in your project?

The control components are a bit light. What does the controller look like, and what kind of interface does it have?

I just want it to drive the motors properly, and a must have is the reverse function since i can't...get off the scooter and turn it myself. I need them to be as powerful as they can be since there's alot of hills where i live. I bought some Chinese controllers and they all disappointed me, that's why i'm looking to build it myself..

The controller was a chinese one, THIS ONE. But drived the motors quite hard, with no PWM and the original hoverboard battery got hot, motors got hot too. And waaay to noisy. Took the original driver out and replaced it with arduino nano. And this is where things got complicated.

This is how it looks for now:

LM317 is missing because it fried at 38V and replaced it with a shunt, now making all the testing on 12V

Your schematic shows three phase motors and MOSFETs. No PWM involved. No wonder they got hot.

I was not clear enough
What does your user input device look like, and what type of interface does it have?

Oh, sorry, english is not my native language. I want to use a simple HALL acceleration to input the speed/power and i want to reverse by activating a switch.

Ok, so turning the wheel is how you steer and the motor just turns both back wheels?

Basically, yes. I used the wheels themselves instead of the original ones.

I don't mind if you suggest a different schematic instead of what i butchered toghether :sweat_smile:

No luck 'till now..

You have mobility differences and live somewhere with lots of hills? Ok, don't do this with Arduino. That's my suggestion. If the problem is with the motor brushes in the scooter, replace the motors in the scooter. Maybe the batteries, too, if they're older. The reverse control on these is often just a little paddle by the handlebars, isn't it?

Point is, if your car has an engine problem, you don't replace the whole ECU. You fix the engine. This is where you should begin. Bit of tough love and I don't mind being the one to say it: looking at your work so far, the plan you're proposing here is going to get you hurt in an accident or at best, stranded. There are certain projects that Arduino ought not do: powered wheelchairs/scooters for people with mobility differences fall squarely into that category. What if it gets wet? How are you protecting the controller from back-EMF and how are you securing the components into something that will be vibrating all the time as you use it?

You're going to spend a lot more time and money on the Arduino solution you're hoping for, than you would just fixing the scooter. Sorry to be so blunt and pessimistic, but as someone whose brother relied on mobility devices for 26 years before he passed away, this is my opinion and you should save the Arduino for another project. Maybe an automatic LED controller to supe up your ride or a battery voltage monitor?

What model is this scooter?

https://www.pcmobilityservices.com/5-most-common-mobility-scooter-problems-and-how-to-fix-them.html

I don't understand this whole thread! Electric motor brushes are one thing that is replaced as a normal part of life. All motor brushes wear out and are made to be replaced.

As I said before, better to just fix the scooter. However, not to come off as ableist, here you go:

/* BLDC Hall Sensor read and calculation program for Teensy 3.5 in the Arduino IDE (Ver.1). Digi-Key Electronics*/

/***************************** Variables *********************************/

#define CW             1			// Assign a value to represent clock wise rotation
#define CCW           -1			// Assign a value to represent counter-clock wise rotation

bool HSU_Val = digitalRead(2);		// Set the U sensor value as boolean and read initial state
bool HSV_Val = digitalRead(3);		// Set the V sensor value as boolean and read initial state 
bool HSW_Val = digitalRead(4);		// Set the W sensor value as boolean and read initial state 

int direct = 1;				// Integer variable to store BLDC rotation direction
int pulseCount;				// Integer variable to store the pulse count

float startTime;				// Float variable to store the start time of the current interrupt 
float prevTime; 				// Float variable to store the start time of the previous interrupt 
float pulseTimeW; 			// Float variable to store the elapsed time between interrupts for hall sensor W 
float pulseTimeU; 			// Float variable to store the elapsed time between interrupts for hall sensor U 
float pulseTimeV; 			// Float variable to store the elapsed time between interrupts for hall sensor V 
float AvPulseTime; 			// Float variable to store the average elapsed time between all interrupts 

float PPM;				// Float variable to store calculated pulses per minute
float RPM; 				// Float variable to store calculated revolutions per minute

/***************************** Setup *********************************/

void setup()
{
// Set digital pins 2, 3 and 4 as inputs
  pinMode(2, INPUT);			
  pinMode(3, INPUT);			
  pinMode(4, INPUT);

// Set digital pins 2, 3 and 4 as interrupts that trigger on rising and falling edge changes. Call a function (i.e. HallSensorU) on change
  attachInterrupt(digitalPinToInterrupt(2), HallSensorU, CHANGE);      
  attachInterrupt(digitalPinToInterrupt(3), HallSensorV, CHANGE);
  attachInterrupt(digitalPinToInterrupt(4), HallSensorW, CHANGE);

// Initialize the print monitor and set baud rate to 9600 
  Serial.begin(9600);
}

/*************************** Main Loop ******************************/

void loop()
{
  if ((millis() - prevTime) > 600) RPM = 0;                                     			// Zero out RPM variable if wheel is stopped

  //Serial.print(HSU_Val); Serial.print(HSV_Val); Serial.println(HSW_Val);      	// Display Hall Sensor Values
  //Serial.println(direct);                                                    				// Display direction of rotation
  //Serial.println(pulseCount);                                                 			// Display the pulse count
  Serial.println(RPM);                            		      			// Display revolutions per minute
}

/************************ Interrupt Functions ***************************/

void HallSensorW()
{
  startTime = millis();						// Set startTime to current microcontroller elapsed time value
  HSW_Val = digitalRead(4);					// Read the current W hall sensor value
  HSV_Val = digitalRead(3);						// Read the current V (or U) hall sensor value 
  direct = (HSW_Val == HSV_Val) ? CW : CCW;			// Determine rotation direction (ternary if statement)
  pulseCount = pulseCount + (1 * direct);				// Add 1 to the pulse count
  pulseTimeW = startTime - prevTime;				// Calculate the current time between pulses
  AvPulseTime = ((pulseTimeW + pulseTimeU + pulseTimeV)/3);	// Calculate the average time time between pulses
  PPM = (1000 / AvPulseTime) * 60;					// Calculate the pulses per min (1000 millis in 1 second)
  RPM = PPM / 90;						// Calculate revs per minute based on 90 pulses per rev
  prevTime = startTime;						// Remember the start time for the next interrupt
}

void HallSensorV()
{
  startTime = millis();
  HSV_Val = digitalRead(3);
  HSU_Val = digitalRead(2);					// Read the current U (or W) hall sensor value 
  direct = (HSV_Val == HSU_Val) ? CW : CCW;
  pulseCount = pulseCount + (1 * direct);
  pulseTimeV = startTime - prevTime;				
  AvPulseTime = ((pulseTimeW + pulseTimeU + pulseTimeV)/3);		
  PPM = (1000 / AvPulseTime) * 60;					
  RPM = PPM / 90;
  prevTime = startTime;
}

void HallSensorU()
{
  startTime = millis();
  HSU_Val = digitalRead(2);
  HSW_Val = digitalRead(4);					// Read the current W (or V) hall sensor value		
  direct = (HSU_Val == HSW_Val) ? CW : CCW;
  pulseCount = pulseCount + (1 * direct);
  pulseTimeU = startTime - prevTime;				
  AvPulseTime = ((pulseTimeW + pulseTimeU + pulseTimeV)/3);		
  PPM = (1000 / AvPulseTime) * 60;					
  RPM = PPM / 90;
  prevTime = startTime;
}

taken from
[https://www.digikey.ca/en/blog/using-bldc-hall-sensors-as-position-encoders-part-3](https://www.digikey.ca/en/blog/using-bldc-hall-sensors-as-position-encoders-part-3)
type or paste code here

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.