Timer1 library

concerning the Timer1 library and I2C communication I have some major questions and querrys, I have a command" analogWrite(rmotorPin,RmotorPinI2C)" .rmotorPin is the Output pin (9),and the RmotorPinI2C
is the variable carrying the PWM pulse from the hand controller, the question is how to Write the Pulse without the analogWrite statement.

Timer1 Library, I'm lost, I tried to use the analog write function but I can't get my motor to turn at speeds as low as 2.8 ms with the freq. standard in the Arduino. The devise which I am trying to copy delivers a freq. of 85 Htz with a pulse of 2.47 ms. I am trying to use the Timer1 library but I am Confused with the commands " pwm (pin,duty,period) ,and void pwm (char pin, int duty, long microseconds=-1), and void set PwmDuty(char pin,int duty); Need example on how to use and please no serial.

For low frequencies why not just use micros() to manage the timing as illustrated (for millis() ) in Several Things at a Time

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

I am looking at the timer1 Library under the heading of Method Detail and I see two statements,
(1) "void setPeriod(long microseconds);
(2)void pwm(char pin, int duty, long microseconds=-1);
How do I set up and use them in my sketch.
I am sending sketch in next post.

Why have you another Thread with the same name and apparently about the same project?

Double posting just wastes everyone's time.

I am suggesting to the Moderator to merge them.

...R

You are better off using slightly different library functions.

Timer1.initialize(long microseconds) will set the period in microseconds, and will make sure the timer registers are properly preset. .initalize() actually calls .setPeriod(). For your code with 85 Hz pwm use

Timer1.initialize(11765);

Then use Timer1.pwm(char pin, unsigned int duty) to set the duty cycle. Duty cycle for that function is going to be some percentage of 1023.

Your duty cycle is 2.47 ms out of a period of 11.765 ms is about 21%. Then (2.47/11.765)*1023 = 215.

So, for 21% duty cycle at 85 Hz on pin 9 you would use

Timer1.pwm(9, 215)

Pin 10 is also available for pwm output on Timer1.

I’m setup already to use pin10 in the constants. I’ll send one of my test codes if I can.

#include<TimerOne.h>
          #define pwmRegister OCR1B
          void pwm(char pin, int duty, long microseconds=-1)
          const int rmotorPin = 10;
          const int rdirPin = 12;
          int dutycycle = 0;
          long period  =12000;
          long pulseWidth =40;
          long setPwmDuty =40;
          
          void setup()  {
           pinMode(rmotorPin,OUTPUT);
           pinMode(rdirPin , OUTPUT);
           Timer1.initialize(12000);
           Timer1.pwm(10,40);     }

          void loop()     {
            dutycycle = 40 ;
            Timer1.pwm(rmotorPin, (dutycycle/100)*1023);
            digitalWrite(rdirPin,LOW);
            delay(1000);

I'm setup already to use pin10 in the constants. I'll send one of my test codes if I can.

Same setup, just use pin 10 in the pwm function

Timer1.initialize(11765);
Timer1.pwm(10, 215)

somehow my reply got pushed out of line. Check it out and see why it only works at 100 %.
However my other problem still remains concerning the I2C aspect. If needed I will type out the section of my sketch containing the excerpt tomorrow

You are having problems with integer math and your divisions winding up as 0. Cast to a float, and add a decimal point to the constants. Also, Do not duplicate elements that are within the library.

See this revision

#include<TimerOne.h>
//#define pwmRegister OCR1B
//void pwm(char pin, int duty, long microseconds = -1)
const int rmotorPin = 10;
const int rdirPin = 12;
int dutycycle = 0;
long period  = 12000;
//long pulseWidth = 40;
//long setPwmDuty = 40;

void setup()  {
  pinMode(rmotorPin, OUTPUT);
  pinMode(rdirPin , OUTPUT);
  //Timer1.initialize(12000);
  Timer1.initialize(period);
 //Timer1.pwm(10, 40); not needed
  Serial.begin(115200);
}

void loop()     {
  dutycycle = 40 ;
  Serial.println((float)dutycycle/100 * 1023.0);
  Timer1.pwm(rmotorPin, (float)dutycycle / 100 * 1023.0);
  digitalWrite(rdirPin, LOW);
  delay(1000);
}

I never bother using serial, I look for physical results. I'll try the sketch tomorrow.

Telescopeman:
I never bother using serial,

Oh, go on, break the habit of a lifetime. You know you really want to. :slight_smile:

...R

I never bother using serial, I look for physical results. I'll try the sketch tomorrow.

If you had used Serial prints to show the value of your variables for debugging purposes you would have found a critical bug in your sketch.

The physical results were that there was no pwm output on pin 10. How did that help you find the root cause?

Gona give it a try but I see no reason to use it in the final version.

Just tried your version but no action. Serial monitor printing 0.00 what could be wrong.

Post the code you just ran. The code posted in reply #9 prints “409.20”

I've had a lot of tomorrow's go by since I last went to the forum but I'm back now. I am trying your last sketch now and I will get back to you soon.

Cattledog: I just tried the sketch that you sent me(post # 9) and it works good, but I was wondering if I can increase the resolution in the pulse width, and if I can, How? I have been using a different sketch which gives a lot of resolution. Maybe you can look at it and tell me how to combine them into a simpler form.

#include <TimerOne.h >
           #define  pwmRegister OCR1B

           const byte  rmotorPin         = 10 ;
           const byte  rdirPin              = 8  ;
           long period                        = 20500;
           long pulseWidth                 = 3000 ;
           int RESOLUTION                = 1024 ;
           
           void setup()    
              {
                pinMode(rmotorPin, OUTPUT);
                pinMode(rdirPin ,  OUTPUT);
                Timer1.initialize(period);
                setPulseWidth(pulseWidth);
             }
           void loop()
             {
              }
            boolean setPulseWidth(long microseconds)
              {
                bool ret  = false;
                if(microseconds < period)
                 {
                   int duty = map(microseconds, 0,period, 0,1024);
                   if(duty < 1)
                    duty = 1;
                    if(microseconds > 0  &&duty < RESOLUTION)
                     {
                       Timer1.pwm(rmotorPin, duty);
                       digitalWrite(rdirPin, HIGH);
                        ret = true;
                     }
                  }
                   return ret;
                   delay (100);
              }

Post #9

Timer1.pwm(rmotorPin, (float)dutycycle / 100 * 1023.0)

Alternate sketch you presented

boolean setPulseWidth(long microseconds)
              {
                bool ret  = false;
                if(microseconds < period)
                 {
                   int duty = map(microseconds, 0,period, 0,1024);
                   if(duty < 1)
                    duty = 1;
                    if(microseconds > 0  &&duty < RESOLUTION)
                     {
                       Timer1.pwm(rmotorPin, duty);
                       digitalWrite(rdirPin, HIGH);
                        ret = true;
                     }
                  }
                   return ret;
                   delay (100);
              }

Both codes pass a value from 0 to 1023 to the library for the length of the pulse. There is no difference in resolution.

could you take a look at my expanded sketch and make it simpler and better.

sketch_aug13a.ino (4.64 KB)