AlkaMotors / AM32-MultiRotor-ESC-firmware

Firmware for stm32f051 based speed controllers for use with mutirotors
GNU General Public License v3.0
784 stars 270 forks source link

Feature request: Pwm input parameters #14

Closed Voodoobrew101 closed 3 years ago

Voodoobrew101 commented 3 years ago

I am using MP6531 for my crawler on a wraith32 35A with Spektrum surface tx/rx

I am having some strange arming issues. I have to play with the throttle to get it to arm. Maybe I have constrained the deadband to much and its just noise resetting the input to 0. But almost always I have to set my throttle trim to -2 to -6 or to arm. Being OCD I would like to set it to zero.

So I am asking if can pwmDeadband, pwmHigh, pwmNeutral, and pwmLow can be added and placed near the top of main.c

I use a spektrum remote which has a neutral of 1500, a high of 1900 and a low of 1100 (aproximatly). I do know know where all the relavent values are, I have played with settings in main.c here

          if (bi_direction == 1 && proshot == 0 && dshot == 0){
              if (newinput > 1050) {                            //Voodoo- go forwards
                  if (forward == dir_reversed) {
                      adjusted_input = 0;
                      forward = 1 - dir_reversed;
                      old_routine = 1;
                      zero_crosses = 0;
                  }
                  else{
                      adjusted_input = map(newinput, 1050, 2000, 0, 2000);      //Voodoo-
                                                    //  tempbrake = 0;
                  }
              }
              if (newinput < 950) {                             //Voodoo- go backwards
                  if (forward == (1 - dir_reversed)) {
                      old_routine = 1;
                      zero_crosses = 0;
                      adjusted_input = 0;
                      forward = dir_reversed;
                  }
                  else{
                      adjusted_input = map(newinput, 0, 950, 2000, 0);      //Voodoo-
                  }
              }
              if (newinput >= 950 && newinput < 1050) {                 //Voodoo- Set to neutral
                  adjusted_input = 0;
              }
          }

But there are setting in IO.c that are possibly relavent.

void computeServoInput() {

    int lastnumber = dma_buffer[0];
    for (int j = 1; j < 3; j++) {

        if (((dma_buffer[j] - lastnumber) > 1000)
                && ((dma_buffer[j] - lastnumber) < 2010)) { // blank space

            servorawinput = map((dma_buffer[j] - lastnumber), 1030, 2000, 0,
                    2000);

In the past I have also constrained values like this (this code is from an arduino project)

        pwmOutput = map(pedalInput, pedalMin, pedalMax, forwardMin, reducedForwardMax);
        pwmOutput = constrain (pwmOutput, forwardMin, reducedForwardMax);

just incase the minimum and max are off, I can set my TX/RX to have a pwm of 1000-2000 but what happens when the firmware then gets 1015 from my remote? since the min in the pwm is 1030.

AlkaMotors commented 3 years ago

I agree, it is not very clear, I think on top of making the clearer setting in main we should put some of these settings into eeprom so they can be changed with the config tool.

There are a few things to note. 1)The main control loop takes a newinput value from 0-2000. 2)The signal input takes whatever come from the servo in microseconds and maps it from (1030-2000) to 0-2000. This works great for the digital signals but i its pretty crude and not easily configurable right now. What type of settings would you like to see for now ? start and stop points and dead band? , adding a calibration routine would take a bit more work.

Voodoobrew101 commented 3 years ago

My neutral is 1500, reverse is 1100, forward is 1900 and a dead band of about 25 on each side so 1475 to 1525. I am curious as why the input is limited to 1030 and not 1000. because I can output 1000 from my TX/RX.

AlkaMotors commented 3 years ago

The 1030 amount just the low cutoff, everything below that point is considered to be 1000. This is to allow for arming with a signal of 1015 for example.

Voodoobrew101 commented 3 years ago

here? servorawinput = map((dma_buffer[j] - lastnumber), 1030, 2000, 0, 2000);

Voodoobrew101 commented 3 years ago

oh for non bidirectional stuff? if my neutral is 1500ms, and we map that through (1030, 2000, 0, 2000) then my 1500 neutral is not 1000, it is now 985, which is no longer centered.

an extra map function with something like

if (dma_buffer[j] - lastnumber)<1500 
      then map((dma_buffer[j] - lastnumber), 1030, 1500, 0, 1000);
if (dma_buffer[j] - lastnumber)>1500 
      then map((dma_buffer[j] - lastnumber), 1500, 2000, 1000, 2000);  

would center 1500 back to 1000 which is easier logic to follow in my opinion. but since my remote doesn't send 1000 to 1100 or 1900 to 2000 could it be changed to something like

if ((dma_buffer[j] - lastnumber)>1030 && (dma_buffer[j] - lastnumber)<2000){
      if ((dma_buffer[j] - lastnumber)<pwmNeutral[1500]){ 
           servorawinput = map((dma_buffer[j] - lastnumber), pwmLow[1100], pwmNeutral[1500], 0, 1000);
      }
      else ((dma_buffer[j] - lastnumber)>pwmNeutral[1500]){  
           servorawinput = map((dma_buffer[j] - lastnumber), pwmNeutral[1500], pwmHigh[1900], 1000, 2000);
      }  
}

I don't understand what (dma_buffer[j] - lastnumber) is. Mostly because I don't know what dma_buffer[j] or dma_buffer[0] equals I assume it returns whatever ms signal my reciever puts out? so for me (dma_buffer[j] - lastnumber) should equal 1100 to 1900?

Voodoobrew101 commented 3 years ago

also I dont know what happens with

      if ((dma_buffer[j] - lastnumber)<pwmNeutral[1500]){ 
           servorawinput = map((dma_buffer[j] - lastnumber), pwmLow[1100], pwmNeutral[1500], 0, 1000);

if (dma_buffer[j] - lastnumber) = 1095 does the map function constrain it to 0 or does the world ends maybe add constrain?

if ((dma_buffer[j] - lastnumber)>1030 && (dma_buffer[j] - lastnumber)<2000){
      int someInput = (dma_buffer[j] - lastnumber);
      constrain(someinput, pwmLow[1100], pwmHigh[1900]);
      if (someInput<pwmNeutral[1500]){ 
           servorawinput = map(someInput, pwmLow[1100], pwmNeutral[1500], 0, 1000);
      }
      else (someInput>pwmNeutral[1500]){  
           servorawinput = map(someInput, pwmNeutral[1500], pwmHigh[1900], 1000, 2000);
      }  
}
Voodoobrew101 commented 3 years ago

If you haven't looked at calibration codes before don't over complicate it here is a basic arduino one

  while (millis() < 5000) {
    sensorValue = analogRead(sensorPin);

    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }
  }

So decide when to start calibration and how. maybee something like

if ((dma_buffer[j] - lastnumber)>1030 && (dma_buffer[j] - lastnumber)<2000){
      int someInput = (dma_buffer[j] - lastnumber);
      constrain(someinput, pwmLow[1100], pwmHigh[1900]);

      if ((someInput>(pwmNeutral[1500]+100))&&(Armed=0)){
            Playtune(duskytune);
            while (millis() < 5000) {
                         // record the maximum sensor value
                        if (someInput > pwmHigh) {
                        pwmHigh = someInput;
                        }

                        // record the minimum sensor value
                        if (someInput < pwmLow) {
                        pwmLow = someInput;
                        }
            Playtune(duskytune);
            }
      }                     
      if (someInput<pwmNeutral[1500]){ 
           servorawinput = map(someInput, pwmLow[1100], pwmNeutral[1500], 0, 1000);
      }
      else (someInput>pwmNeutral[1500]){  
           servorawinput = map(someInput, pwmNeutral[1500], pwmHigh[1900], 1000, 2000);
      }  
}

I don't actually know if any of this code will work, and it didn't calibrate neutral position. and it is only going to calibrate PWM raw servo input. I mean obviously it wont work I left the [value] in there for easy reference

AlkaMotors commented 3 years ago

Hey that looks pretty, good, I have been stuck trying to fix some performance issues that I think are solved now so I will add these ideas and changes in next , sorry for putting it off.. they are long overdue. I was thinking about creating a new branch for ground vehicles with its own configurator since it will start diverging a bit from the multi-rotor one.

Voodoobrew101 commented 3 years ago

all the code I made is arduino based, I know its similar but the functions may not work. I would appreciate a crawler branch, There is a bunch of extra stuff like DShot and telemetry that just confuses me and we don't use it. maybe in the future telemetry but meh. if a battery dies in a crawler it doesn't generally fall out of the sky.

I don't have a clue what the core esc functions do as far as performance, acceleration, brakeing, and all that, but..

Dont forget the section main.c where the pwm settings are also.