analogWriteResolution ?

Status
Not open for further replies.

Gadget999

Well-known member
using TEENSY 3.2

does analogWriteResolution(16) set the resolution of all pins or only certain pins ?

i am using pwm on pins 5 and 6 and it appears the pin 6 is a lower resolution and its output is stepped compared to pin 5

pls advise
 
i have tried different pins and different frequencies- the problem is still there

it appears if i sweep the pwm up and down the second pwm channel is stepping

Code:
/*

 */



int MaxVal = 65000;
int CH1PWM = 0;
int CH2PWM = 0;
int CH3PWM = 0;
int CH4PWM = 0;
int DataStamp = 20000;
bool GotData ; 

String incomingStr ;
String ReadStr ;

// we are using 4 pwm ch pins 5,6,9,10

void setup() {

  analogWriteResolution(16);
  
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(13, OUTPUT);
  analogWriteFrequency(5, 108);
  analogWriteResolution(16);
  analogWriteFrequency(6, 108);
  analogWriteResolution(16);
  analogWriteFrequency(9, 108);
  analogWriteResolution(16);
  analogWriteFrequency(10, 108);
   analogWriteResolution(16);
 
  Serial.setTimeout(1);
  Serial.begin(115200);

  analogWriteResolution(16);
 
}


void loop() {
  // set the pwm outs

  ReadDataStream();

  
  analogWrite(5, CH1PWM);
  analogWrite(6, CH2PWM);
  analogWrite(9, CH3PWM);
  analogWrite(10, CH4PWM);

  //analogWrite(13, (CH1PWM + CH2PWM) / 2);


  digitalWrite(13, GotData);
  
    if (millis() > DataStamp + 5000){
      
        CH1PWM = 0 ;
        CH2PWM = 0 ;
        CH3PWM = 0 ;
        CH4PWM = 0 ;
        
        analogWrite(5, 0);
        analogWrite(6, 0);
        analogWrite(9, 0);
        analogWrite(10, 0);

        GotData = false ;
        digitalWrite(13, GotData);
        
  }
}


void ReadDataStream()
{
          if (Serial.available() > 0) {
                GotData = not(GotData);
                DataStamp = millis() ;
                incomingStr = Serial.readString();
                Serial.println(incomingStr);
                if (incomingStr.startsWith("CH1")) {
                 ReadStr =  incomingStr.substring(3, 9)     ;
                 CH1PWM = ReadStr.toInt();
                 if (CH1PWM > MaxVal){
                    CH1PWM = MaxVal ;
                    } 
                 }
                 if (incomingStr.startsWith("CH2")) {
                 ReadStr =  incomingStr.substring(3, 9)     ;
                 //Serial.println(ReadStr);
                 CH2PWM = ReadStr.toInt();
                 //Serial.println(CH2PWM);
                 if (CH2PWM > MaxVal){
                    CH2PWM = MaxVal ;
                    }
                 }

                 if (incomingStr.startsWith("CH3")) {
                 ReadStr =  incomingStr.substring(3, 9)     ;
                 //Serial.println(ReadStr);
                 CH3PWM = ReadStr.toInt();
                 //Serial.println(CH3PWM);
                 if (CH3PWM > MaxVal){
                    CH3PWM = MaxVal ;
                    }
                 }

                 if (incomingStr.startsWith("CH4")) {
                 ReadStr =  incomingStr.substring(3, 9)     ;
                 //Serial.println(ReadStr);
                 CH4PWM = ReadStr.toInt();
                 //Serial.println(CH4PWM);
                 if (CH4PWM > MaxVal){
                    CH4PWM = MaxVal ;
                    }
                 }   
            
          }                 
}
 
Any chance you could try a program which automatically sweeps the PWM gradually, without requiring communication from your computer?

While you did give us a complete program, it appears to depend on receiving certain data to actually do anything. We can't just run that on a Teensy to reproduce the problem. A program which just gradually changes the PWM without USB communication would be ideal for trying to troubleshoot only the PWM stuff.

If this does turn out to be a problem with the communication stuff, we might be able to help with that too... but without having the data or program which sends the data, pretty much impossible to try reproducing the problem.
 
Any chance you could try a program which automatically sweeps the PWM gradually, without requiring communication from your computer?

While you did give us a complete program, it appears to depend on receiving certain data to actually do anything. We can't just run that on a Teensy to reproduce the problem. A program which just gradually changes the PWM without USB communication would be ideal for trying to troubleshoot only the PWM stuff.

If this does turn out to be a problem with the communication stuff, we might be able to help with that too... but without having the data or program which sends the data, pretty much impossible to try reproducing the problem.

Hi Paul,

I was just thinking the same and came to check the forum !

I think the serial communication is tripping over itself and the allocation of the first channel is getting updated whilst the other channels are getting missed


i will write a small program to cycle the pwm up and down and report back :)



what do i need to do to improve serial comms and make sure data is not missed / ignored ?

also should I be using a proper hardware serial port rather than the usb over serial ?
 
small program to cycle pwm

it seems to work perfectly with no steps :)

Code:
int PWMVal = 0;
int I = 0;
int Step = 1;


void setup() {
  
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

  analogWriteResolution(16);
  
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(5, I);
  analogWrite(6, I);
  analogWrite(9, I);
  analogWrite(10, I);

  
  I  = I + Step;

  
  if (I <= 0 || I  >= 65535) {
    Step = -Step;
  }
  
  delay(1);
}
 
what do i need to do to improve serial comms and make sure data is not missed / ignored ?

Hard to say without seeing the details, like what you're doing to transmit.

Since you're using ASCII text, maybe try sending from the Arduino Serial Monitor. Then you can print extra info to help you figure out what's going wrong. And if you get stuck, you can give us the exact text to copy into the serial monitor's "send" line. We're much better at helping here when we have a complete program *and* a way to make it reproduce the problem....


also should I be using a proper hardware serial port rather than the usb over serial ?

USB serial is very reliable, moreso than normal hardware serial because the USB protocol automatically has flow control (so you can't miss incoming data if your code is busy) and the USB checks for errors and automatically retransmits any corrupted packets.

My guess is this is a code issue that will probably have exactly the same problem over regular hardware serial. I'd stick with USB serial.
 
basically the windows app sends for example "CH1500"

CH1 is the channel Number followed by the PWM value

it appears the first channel always send the data cleanly
the second channel is sent and sometimes there is a delay processing it on the Teensy
Code:
void ReadDataStream()
{
          if (Serial.available() > 0) {
                GotData = not(GotData);
                DataStamp = millis() ;
                incomingStr = Serial.readString();
                Serial.println(incomingStr);
                if (incomingStr.startsWith("CH1")) {
                 ReadStr =  incomingStr.substring(3, 9)     ;
                 CH1PWM = ReadStr.toInt();
                 if (CH1PWM > MaxVal){
                    CH1PWM = MaxVal ;
                    } 
                 }
                 if (incomingStr.startsWith("CH2")) {
                 ReadStr =  incomingStr.substring(3, 9)     ;
                 //Serial.println(ReadStr);
                 CH2PWM = ReadStr.toInt();
                 //Serial.println(CH2PWM);
                 if (CH2PWM > MaxVal){
                    CH2PWM = MaxVal ;
                    }
                 }

                 if (incomingStr.startsWith("CH3")) {
                 ReadStr =  incomingStr.substring(3, 9)     ;
                 //Serial.println(ReadStr);
                 CH3PWM = ReadStr.toInt();
                 //Serial.println(CH3PWM);
                 if (CH3PWM > MaxVal){
                    CH3PWM = MaxVal ;
                    }
                 }

                 if (incomingStr.startsWith("CH4")) {
                 ReadStr =  incomingStr.substring(3, 9)     ;
                 //Serial.println(ReadStr);
                 CH4PWM = ReadStr.toInt();
                 //Serial.println(CH4PWM);
                 if (CH4PWM > MaxVal){
                    CH4PWM = MaxVal ;
                    }
                 }   
            
          }

my guess is the code reading CH2 get interrupted by fresh data coming into the serial port

i will try slowing down the sending to the serial port to see if that helps - but i cant use that a permanent solution
 
I programmed some delays in the windows app transmitting the data and the problem went away.

However i can not use this as a solution, the teensy is replacing the existing board and it needs to be backwards compatible.

So its seems the serial chip on the teensy is getting flooded ?

Is the arrival of serial data interrupting the main loop ?

How long does it take for the teensy to perform a analogue write ?

Can the serial buffer be increased or flushed to stop an overload ?

Any suggestions appreciated
 
Status
Not open for further replies.
Back
Top