Jump to content

Firmware


jayjay23

Recommended Posts

Correction. Each transition of hall sensor signals happen at 5ms. 1 rotation per second of the wheel is 1 second / 46 magnets = 0.0217 (21.7ms per magnet). At 5ms per magnet, the wheel rotates at 21.7/5 = 4.34 rotations per second. Th wheel perimeter is 1.12 meters, so, 4.34 * 1.12 * 60 * 60 = 17.5km/h <--- is this value correct? the velocity limit for generic EUCs is also 18km/h....

https://github.com/generic-electric-unicycle/documentation/wiki/Controllers

The change from 1st to 2nd way to control the motor seems to happen when the transition of hall sensors signal are about 10ms period (2 transitions at each 10ms - at about 17.4km/h speed):

control_method_change_speed-01.bmp

control_method_change_speed-02.bmp

  • Upvote 1
Link to comment
Share on other sites

17 hours ago, Mystamo said:

Perhaps this brings us back to the possibility of using the GEN 2 hardware since the GEN 1 as I had posted a while earlier is an outdated and in efficient design in running the EUC.

I've finally finished putting the board schematics together. Here is a sneak peak. I'll post the schematics into the hardware forum after I make a few more corrections and modifications.

I still need to route this board. But i'm waiting for feedback as well as improvements and added features before I waste my time doing that.

Great work so far on the firmware .

Regards,

 

Mo

EUC GEN 2.jpg

Do we know what the J connectors are for?

CAN bus and SPI for future use/ debugging

currently regulations are stating the need of redundancy to get street legal. I'll do with a colleague a hazard and risk analysis and risk calculation based on the appropriate standard. I'll try to get away from redundancy with a really proper designed soft-/ hardware. If we found that we still need this we can use SPI for sync between two boards.

Link to comment
Share on other sites

I don't think the existing boards are worth developing further. They're nothing more than a poor quality BLDC controller with a gyro. Even with redundant  MCUs nothing is well protected from surges and voltage drops so it won't be much safer. There's not really anything worth salvaging from the design.

Link to comment
Share on other sites

1 hour ago, lizardmech said:

I don't think the existing boards are worth developing further. They're nothing more than a poor quality BLDC controller with a gyro. Even with redundant  MCUs nothing is well protected from surges and voltage drops so it won't be much safer. There's not really anything worth salvaging from the design.

It's a question when which design step will be available and if we can see other modules working on a better than the old 18 km/h board (Bluetooth). With this step in between firmware can be developed further on to be more ready for the target board.

Link to comment
Share on other sites

37 minutes ago, OliverH said:

It's a question when which design step will be available and if we can see other modules working on a better than the old 18 km/h board (Bluetooth). With this step in between firmware can be developed further on to be more ready for the target board.

I don't know if the motor code will be able to be reused much if the board is changed, the gyro and balancing code should be more portable though.

Link to comment
Share on other sites

The max current control is working well, and for my surprise, it works well for a low value like 1A and this means that will work well for values from 1A up to 6A or more - I think is possible to implement torque control :-) -- since we can define the current and we know the battery voltage.
You will see on the video, that at 1A, the motor rotates very fast at about 22km/h (hall sensor signal transition at ~4ms).

On the video, I use the potentiometer and I am turning it full to left and right and without current control the current would be much higher than 1A... also I verified in oscilloscope that at max the potentiometer the duty-cycle is really getting cut some parts of time as it should.

On the code, there is a variable that setups the value at were the firmware will start shutting down the duty-cycle. That is the value the ADC measures from the current signal: 

/*
 * 0 Amps = 1.54V
 * each 1A = +0.0385V
 * 12 bits ADC; 4096 steps
 * 3.3V / 4096 = 0.0008
 *
 */

#define ADC_WATCHDOG_HIGHTHRESHOLD ((1.54 + (0.0385 * 1/*amps*/)) / 0.0008)

unsigned int adc_watchdog_highthreshold = ADC_WATCHDOG_HIGHTHRESHOLD

For some reason, the motor rotates to right at fast speed but for left it rotates at lower speed using the same current - can be seen on the video - this means that the code to control the motor needs to be improved. Anyway, it works good enough right now including the current control.

Also I implemented the code to read the battery voltage.

Things that need to be done:

  • implement the code to read the IMU signal
  • implement simple code to control the motor using the IMU code (first code to work as EUC)
  • improve motor control code

Please get/read the current code here: https://github.com/generic-electric-unicycle/firmware

 

 

Edited by electric_vehicle_lover
  • Upvote 3
Link to comment
Share on other sites

@electric_vehicle_lover:

This findings is really great, actually I thought that current control should be possible. Even I'm not really finished I put up back the wheel stuff to my desk and will try the math stuff next days, so far I was busy with this stuff (eib bus components for our house) and also had some time shortage due to child care special situation which hopefully clears next weeks:

img_1009924_small.thumb.jpg.f2477ad61144

 

This week is so warm here in germany that I started to go by wheel again (I didn't wanted to try on ice, thoug vee has a really cool spikes mod :-))

Link to comment
Share on other sites

@Mystamo I can't give much feedback now since I am learning how the motor works and the system. I know that I miss a lot bluetooth for debug/control propuses just like the generics V2 boards have. Also I would like to have an expansion board like Arduino so I could build other functionalities like RGB LED bar.

@jayjay23 please share your code, maybe on a git branch. I started reading the MPU6050 datasheet...

Link to comment
Share on other sites

Regarding the MPU it goes like this, the lib just read the register map (RM-MPU-6000A.pdf) starting from ACCE_XOUT_H, 14 bytes, this is all these values:

ACCEL_XOUT_H
ACCEL_XOUT_L
ACCEL_YOUT_H
ACCEL_YOUT_L
ACCEL_ZOUT_H
ACCEL_ZOUT_L
TEMP_OUT_H
TEMP_OUT_L
GYRO_XOUT_H
GYRO_XOUT_L
GYRO_YOUT_H
GYRO_YOUT_L
GYRO_ZOUT_H
GYRO_ZOUT_L
 

So you get a 14 byte array as above.

   s16 mpuData[8];
   MPU6050_GetRawAccelGyro(mpuData);
   
   // HINT we define here the board orientation (may subject to change/configure)
   
   int16_t upDownAccel    = mpuData[0];
   int16_t frontBackAccel = mpuData[1];
   int16_t leftRightAccel = mpuData[2];
   
   int16_t frontBackGyro = mpuData[4]; // just a guess
   int16_t leftRightGyro = mpuData[5];

This is the none DMA example.

In init you set the scale of the values, the int16 is -16k to +16k and the scale defines what's the rang in physical units. So

if you set the accel scale to 16G (MPU6050_ACCEL_FS_16) this means -16k is -16G (or half, not sure right now). So to get

a physical unit G value you just need to divide properly. So the scale also defines the sensitivity, you could decide to go for a

smaller scale to have more sensible values, meaning each integer step is a smaller - so more precise - physical step.

The same applies for the gyro, physical unit is rad/s.

 

From this point I just used some basic trigonometry (while I'm not 100% sure, whether I choose the correct observer point of view, as I don't know what the  filters expect, but I guess they can work with any value, it's how we feed the result in the PID loop and it's our own decision how the filter/PID output is converter to rotation):

   // PI/2 - acos([frontBackAccel|leftRightAccel]/16383,5)
   float fwBkAccelAngle       = PI/2.0 - acos(frontBackAccel/16383.5);
   float leftRightAccelAngle  = PI/2.0 - acos(leftRightAccel/16383.5);
 
   // calculate gyro rate in rad/s
   float fwBkGyroRadS = frontBackGyro/5000;
   
   uint16_t loopTime = utilDelayCnt;
   
   *fwBkAngle = callFilter(fwBkOldAngle, fwBkAccelAngle, fwBkGyroRadS, loopTime);
   fwBkOldAngle = *fwBkAngle;

 

Here the constant dividers (16k and 5k) are just plain wrong, they need to be carefully adjusted according to the scale choosen, bu this was actually

the point were I left of due to float instability.

I wanted to try that code tonight, but for some reason my programming adapter didn't wanted to connect. Anyway I hope above explanation

makes looking through the spec shorter.

  • Upvote 1
Link to comment
Share on other sites

20160129_223555.thumb.jpg.2c9e916a3d89ae

I bought another generic EUC to share with other family members :-)

The acceleration seems to be softer/slower.

The board uses a chinese clone of STM32F130 that should run at faster speed, etc.

http://www.gigadevice.com/product-category/15.html

https://endless-sphere.com/forums/viewtopic.php?f=35&t=71867


Also the board have a 4 pin header for "F_WRITE" and another for "DEBUG" that I bet is the serial port connection!!!

I will document on the wiki this board.

Edited by electric_vehicle_lover
Link to comment
Share on other sites

@jayjay23 thanks for IMU code!! I were able to IMU_init () and the MPU6050_TestConnection () reads correctly the 0x34 value for the WHO_AM_I.

I tried after the Init to MPU6050_GetRawAccelGyro () but I got nothing from the sensor. I need to read mre the code to understand the DMA, etc...

I plan to use and flashing LED frequency to "visualize" the angle output (I also plan to use the Kalman implementation you have). If the LED is not enough, I will need to try solder the pins for the UART on the PB10 and PB11 - shouldn't be easy :-(

Link to comment
Share on other sites

@jayjay23 finally I got the IMU working :-)

   //reset the whole module first
   MPU6050_Write(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1, 1<<7);

   delay_ms(50); //wait for 50ms for the gyro to stable

First it wasn't working and I found that the 50ms delay that were commented is needed. I implemented the delay_ms () and the IMU now works.
May next I will implement, as you started, the DMA code, before follow to the Kalman filter testing.

  • Upvote 1
Link to comment
Share on other sites

Well, found that would be kind of impossible to develop the IMU code without serial data output. I decided to add the HC06 cheap Bluetooth serial module. The only available USART pins I had available were used by some pins of H bridge and so I used them - this means this board will only be for this task - anyway, most mosfets are already burned anyway :-)

I really miss printf () to print floats and it's not working, I need to put it working. For now, it works for printing signed ints and so I printed the X, Y and Z axis values of the accelerometer. I used low pass filter (average) and I found:

// Y axis gives the front/rear inclination of the wheel --> we will use it to accelerate/decelerate the wheel.
// Z axis gives the lateral inclination of the wheel --> we will use it to understand when the wheel will get on the horizontal meaning we will need to shutoff the motor.

56b290d68619e_2016-02-0315.02.45.thumb.jserial_log.thumb.png.cc77cc0051717fa7f63

  • Upvote 2
Link to comment
Share on other sites

With serial data out, I were able now to get the angle value working!! but for now just using accelerometer value, after a low pass filter/average and the calc to get the angle value in degrees - please see the video I just registered. Next I hope to move forward by using a complementary filter -- OpenSource projects like Arduino and Github services rocks!!

 

 

Edited by electric_vehicle_lover
  • Upvote 3
Link to comment
Share on other sites

  • 2 weeks later...

I quick documented some signals of the new generic EUC board I have: https://github.com/generic-electric-unicycle/documentation/wiki/Generic-EUC---GD32F130-microcontroller

This Generic EUC is not rideable because it seems to have low current configured -- I really need to finish our OpenSource firmware to make this EUC useful for my girlfriend :-)

 

---

Generic EUC GD32F130 microcontroller

casainho edited this page a minute ago · 7 revisions

This generic EUC was bought on Ebay and was really cheap (280€ including the tax and shipping to Portugal, on January 2016).

It is underpowered and slow, even if the battery, motor and controller board seem to be similar with other more powerful generic EUCs. As a guess, seems that the lack of power is due to a low current configuration on the firmware.

Although the board uses GD32F130 microcontroller, which is a chinese clone of STM32F103 microcontroller (See more here about this.), it is very similar with other generic EUC boards:

generic_EUC-2016.01-01.jpg

generic_EUC-2016.01-04.jpg

generic_EUC-2016.01-02.jpg

generic_EUC-2016.01-03.jpg

Also the board have a 4 pin header for "F_WRITE" and another for "DEBUG" that I bet is the serial port connection!!! There is no data out on the debug port while the firmware is running.

Pictures of electrical signals

Yellow: hall sensor signal. Blue: motor phase 1 signal. The motor was running at a "high speed". The duty-cycle of the PWM signal were almost 95%:

generic_EUC-2016.01-osci_01.bmp

generic_EUC-2016.01-osci_02.bmp

Here we can see that there is a linear transition of the duty-cycle value, when the change on the hall sensor value. This is the first time I see such linear transition on a generic EUC:

generic_EUC-2016.01-osci_03.bmp

generic_EUC-2016.01-osci_04.bmp

generic_EUC-2016.01-osci_05.bmp

generic_EUC-2016.01-osci_06.bmp

Here the PWM frequency:

generic_EUC-2016.01-osci_07.bmp

Yellow: motor phase 1 signal. Blue: motor phase 2 signal. Here the motor was stopped:

generic_EUC-2016.01-osci_08.bmp

And here with some rotation:

generic_EUC-2016.01-osci_09.bmp

 

 

  • Upvote 1
Link to comment
Share on other sites

Finally I found and corrected a bug in the IMU initialization code. Now the sensor values output correctly.

Also the complementary filter seems to work, when comparing the angle value before and after the filter, I see less oscillation on the values (testing while quickly oscillating the electronic board from forward <-> backward). Here is the actual code: https://github.com/generic-electric-unicycle/firmware/tree/master/src

 
BOOL IMU_read(void) {
  float acc_x;
  float acc_y;
  float angle;
  static float gyro_rate;
  float dt;
  unsigned int micros_new;
  static unsigned int micros_old = 0;
  static unsigned int timer_1s = 0;
   
  // read the accel and gyro sensor values
  MPU6050_GetRawAccelGyro (accel_gyro);
   
  acc_x = accel_gyro[0];
  acc_y = accel_gyro[1];
  gyro_rate = accel_gyro[4] * GYRO_SENSITIVITY;
   
  // calc dt, using micro seconds value
  micros_new = micros ();
  dt = (micros_new - micros_old) / 1000000.0;
  micros_old = micros_new;
   
  angle = atan2(acc_x, acc_y); //calc angle between X and Y axis, in rads
  angle = (angle + PI) * RAD_TO_DEG; //convert from rads to degres
  angle = 0.98 * (angle + (gyro_rate * dt)) + 0.02 * (acc_y); //use the complementary filter.
   
  timer_1s++;
  if (timer_1s > 99)
  {
  timer_1s = 0;
   
  printf ("new_angle: %6.6f : \n", angle);
  }
  }
Edited by electric_vehicle_lover
  • Upvote 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...