how do i read and output pwm with a black pill board?

I am making an stm32 based motor speed controller for a DC motor. But I can't read PWM off my receiver and I can't make my MOSFET vary the output! I need help because now it's only on or off! I am using a RobotDyn BlackPill and an STP36NF06L Mosfet. And also I use Arduino ide with the STM board. Code: unionwell portugal

int Motor = PA15;
int rc = PB1;
int s;


void setup() {
  pinMode(Motor, OUTPUT);
  pinMode(rc, INPUT);
  digitalWrite(Motor, LOW);
}
void loop() {
   if(s = (map(pulseIn(rc, HIGH), 1100, 1900, 0, 255)) > 200) {
    digitalWrite(Motor, HIGH);
  }
  else{
    digitalWrite(Motor, LOW);
  }
  delay(10);
}
if(s = (map(pulseIn(rc, HIGH), 1100, 1900, 0, 255)) > 200)

Is this how you do a comparison between 2 values in C, or is something important missing such as a second = ?

The signal from the receiver is it PWM or PPM?

The signal for each servo is PWM but these signals are within a PPM data stream

It is PWM. Someone reposted my question here is the original forum post: arduino - how do i read and output pwm with a black pill board? - Stack Overflow

at least i think, its from a 2.4ghz reciever

I use this to map the PWM signals, and then it works like: if the signal is over 200 then its on, else its off. But When i do this i dont get a clean 0-255 i get like 115-300 something!

If program works and result is in range from 115 to 300, try change ranges in map function. Maybe 'map ( pulseIn ( rc, HIGH ), 1460, 2040, 0, 255 )'!? I just guess.

yeah but my problem is that i cant control the speed of the motor it doesnt really matter if get this working :frowning:

Yes, that makes your program. For PWM over 200 out of 255, it turns on the engine, otherwise it stops. Now you say you want to smoothly adjust the engine, right? Then you need another program.

int Motor = PA15; // pin must be with PWM output
int rc = PB1;
int s;

void setup ()
{
  pinMode ( Motor, OUTPUT );
  digitalWrite ( Motor, LOW );
  pinMode ( rc, INPUT );
}

void loop ()
{
  // s = map ( pulseIn ( rc, HIGH ), 1100, 1900, 0, 255 );
  s = map ( pulseIn ( rc, HIGH ), 1460, 2040, 0, 255 ); // if PWM on motor pin is 8bit
  if ( s > 20 ) // threshold for start of motor if needed
    analogWrite ( Motor, s );
  else
    digitalWrite ( Motor, LOW );
  delay ( 10 );
}

Yes, my goal was to control the motor's speed! The code that's shown is my workaround while I find the perfect script for me.


This is how it looks when im not inputting any controls!

Here i pressed fully on, and reverse!

int Motor = PA15; // pin must be with PWM output
int rc = PB1;
int s;

void setup ()
{
  pinMode ( Motor, OUTPUT );
  digitalWrite ( Motor, LOW );
  pinMode ( rc, INPUT );
  Serial.begin(9600);
}

void loop ()
{
  s = map ( pulseIn ( rc, HIGH ), 1010, 1810, 0, 255 );
  int s2 = map(s, 120, 306, 0, 255);

  if (s2 > 0) {
    s2 - 45;
  }
  else if (s2 > 50) {
    analogWrite ( Motor, HIGH );
  }
  else if(s2 < 5){
    //reverse
  }
  else {
    digitalWrite ( Motor, LOW );
    delay ( 10 );
  }


    Serial.println(s2);
}

If you want to read an external PWM signal you can use a timer in input capture mode, such that one channel triggers on the rising edge and the other triggers on the falling edge then compute the period and as such the frequency and duty cycle of the incoming signal. It is well documented in the reference manual and there are various examples and even YouTube tutorials of input capture mode.

#Copied

yes, but how can I put the stm in capture mode if I'm using an Arduino flashed STM board?

There at least 2 different cores for STM boards, and 'black pill' is also not a exakt description of your board and processor. Which are you using?

This one: https://robotdyn.com/black-pill-apm32f103cb-128kb-flash-20kb-sram-stm32-compatible-arm-cortexr-m3-mcu-mini-board.html

Can you explain in words the relationship between the input signal and the desired output?
A PWM signal has a frequency component and duty cycle component.
For the input, I suppose you are interested in only the duty cycle but must make the assumption that the frequency is not too high to be handled by code in the loop.
The motor you are driving will also require a specific range .
You appear to be using analogWrite() but with a binary value for the duty cycle. Usually the resolution for the duty cycle is 8bits (a value between 0 and 255).
Can you also explain how reverse has to be handled? It is mentioned in one of the diagrams.

So I need to read PWM from an RC receiver, and I need to output a 0-255 for a Mosfet (that controls the high current motor). And for reverse, I am either gonna make another Mosfet circuit or I am gonna just put a relay that instantly powers the motor backwards. (i will probably do the first one)
I don't know a lot about PWM, I actually just started to explore it so that means I will probably not understand half of what you are saying about PWM. I also don't know how to use bits in a program, i hope to learn that one day.

How is a reverse command encoded into that PWM signal you read from the RC Receiver ?

You have shown a picture in post #12 which may have a voltage scale on the Y axis and it can have a negative value. What is that ?

You can test the motor control separate from the code to interpret the output from the RC Receiver. Just use analogWrite( pin, n ) where n is a number from 0 to 255.

To reverse a DC motor, you can use an H bridge chip e.g. L293D but choose one appropriate for the power requirements of the motor. This would also replace your Mosfet. You can also use a DPDT relay but then you need the Mosfet to pulse the pulse the power because a relay can not be operated at PWM type frequencies.

I'm guessing that this project is school assignment.

The reverse comes from the value going in -. In the #12 picture i have described what i am doing and what is happening in the console. And this isnt really a school project, i am building a diy drift car.