Multiple PWM outputs interaction

msaine

Active member
Am I wrong believing the Teensy can support multiple PWM outputs at the same time? I am working on a simple multiple motor controller and can only seem to get one motor at a time to work. Here is a snipet of the code:


Val = (constrain(msg->mtr_A, 0, 511)); // msg should be in range 0-512
if ( Val & 0x100) // is direction negative
{
bitClear(Val,8);
digitalWrite(ADIR, HIGH);
if ( Val < DEADBAND)
{
Val = 0;
}
analogWrite(APWM, Val);
}
else
{
digitalWrite(ADIR, LOW);
Val = 0x100-Val;
if ( Val < DEADBAND)
{
Val = 0;
}
analogWrite(APWM, (Val));
}

Val = (constrain(msg->mtr_B, 0, 511)); // msg should be in range 0-512
if ( Val & 0x100) // is direction negative
{
bitClear(Val,8);
digitalWrite(BDIR, HIGH);
if ( Val < DEADBAND)
{
Val = 0;
}
analogWrite(BPWM, Val);
}
else
{
digitalWrite(BDIR, LOW);
Val = 0x100-Val;
if ( Val < DEADBAND)
{
Val = 0;
}
analogWrite(BPWM, ( Val));
}

At this point only 1 motor seems to function at a time. APWM is A9 and BPWM is A7 if that matters.

I know there is something simple I'm missing but currently at a loss as to why only one output works at a time.
 
I don't see anything obviously wrong in the code, but we're only looking at a snippet. We can't see the definition of Val, or how you configured PWM resolution and frequency, or whether you might have used pinMode() or done some other configuration that could cause a conflict. We don't know what hardware you're using, or what you mean by "only one output works at a time". Can you specify which Teensy you are using and provide write a small working program that calls this code and shows a problem? Also, please use the "#" button and paste your code between the resulting CODE and /CODE markers, so it stays formatted.
 
I don't see anything obviously wrong in the code, but we're only looking at a snippet. We can't see the definition of Val, or how you configured PWM resolution and frequency, or whether you might have used pinMode() or done some other configuration that could cause a conflict. We don't know what hardware you're using, or what you mean by "only one output works at a time". Can you specify which Teensy you are using and provide write a small working program that calls this code and shows a problem? Also, please use the "#" button and paste your code between the resulting CODE and /CODE markers, so it stays formatted.

The whole file, a work in progress so numerous commented out code lines and probably stuff that no longer applies :)

View attachment body03B.ino


As far as working one at a time: Transmitter sends a message that this module receives and has PWM values in the message block. The snippet I included reads each motors value and sets Val and then does an analog write to appropriate PWM pin. By not working at same time I mean only one motor will move when both values are changed in the message. Sorry about the formatting problem, posting here with code is not something I have much practice with. I hope the above attached file is correct. Not sure if I can do a program that uses the code as a test.
 
I can't build your program, but if you just want to know whether you can have PWM on both pins at the same time, try running this program. If you get PWM on both pins, then you can start debugging your program.

Code:
#define APWM A9
#define BPWM A7

void setup() {
	Serial.begin(115200);
	delay(1000);

	analogWrite( APWM, 128 );		
	analogWrite( BPWM, 128 );	
}

void loop() {
}
 
First, let me clearly state all the PWM pins can have their PWM duty cycle controlled independently. Your program doesn't seem to be controlling the frequency. But if you did, the independent nature of every PWM pin is only for duty cycle. Groups of pins have the same frequency, so if you were controlling frequency you would have a situation where 1 pin could affect the others. But for ordinary control of PWM duty cycle, all the PWM pins can be controlled independently. Changing any PWM pin with analogWrite() affects only that specific pin and leaves all the others as they were.

Now, that answered, some questions....

Which Teensy model are you using? Probably an older one? On Teensy 4.0 and 4.1, pin 21 (A7) does not have PWM capability.

I tried briefly to read body03B.ino, but it's lacking definitions for things like "struct lbody_msg" and "lbody_m". Maybe those are in body.h?

Looking at the process_msg() function, maybe you should consider adding code to overwrite the message buffer with zeros or other easily detected invalid data when you're done using it. Maybe it's overly paranoid, but as nearly as I can see from only a quick look at the code, there doesn't seem to be any checks that the message was fully received and valid. Or maybe RF24NetworkHeader checks it? In any case, it wouldn't hurt for troubleshooting to fully wipe the just-consume message, so if you're suffering some sort of problem with short or incorrect communication you can't accidentally end up reusing some or all of a prior message.
 
Hi @all,

for all who are interested in controlled frequenecy signals via PWM synthesis,
one can have a look at the lecture of

https://www.google.com/search?q=pwm+cricket+tutorial+pico+hunter+adams

That is for the PICO, but should be adaptable for the Teensy Audio library, too.

In one of the lectures (I think about the frequency synthesis around - "cardinal-birds" )
they describe an algorithm how to crate a very precise frequency using reoeated interrupts with variable delay.

The PWM signal is toggeled at each interrupt and then set asleep depending on the frequency of the recent time-slot.

This gives 1 frequency PWM signal by interrupt routine .

Hope this helps,
- Frank
 
Back
Top