Pages: [1]   Go Down
Author Topic: TimerPWMCheatsheet  (Read 1035 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i have a NANO and want to set the 0 timer to 62.5k so i have followed this guide
http://arduino.cc/playground/Main/TimerPWMCheatsheet

While changing it to 62.5k does work editing the wiring.c has no affect

i then thought i could just increase my delay by 64 times. This does make it appear to count at the correct rate however my DHT11 humidity sensor doesn't work.

Any thoughts guys 
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13702
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


you state several problems / solutions.

What is the real problem you want to solve?

The DHT11?  use a library that doesn't use delay to read it e.g. - http://arduino.cc/playground/Main/DHT11Lib -

(however it uses micros() that could be affected too by changing timer0 ...
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well i dont mid what the solution is to my problem but i want 62k and the  DHT11 working.

if it was a simple timing issue i would have though it would have worked when i multiplied the time by 64
Logged

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12161
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


you state several problems / solutions.

What is the real problem you want to solve?

The DHT11?  use a library that doesn't use delay to read it e.g. - http://arduino.cc/playground/Main/DHT11Lib -

(however it uses micros() that could be affected too by changing timer0 ...

Will be affected - most of the time stuff (delay(), millis(), micros() - but not delayMicroseconds()) is totally relying on timer0.  Use a different timer if you don't want to upset things.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks for the suggestion . i

however that didn't help
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18764
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Read this before posting a programming question
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

um thanks ? but i dont believe that has any relevance ?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18764
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
i have a NANO and want to set the 0 timer to 62.5k so i have followed this guide
...

While changing it to 62.5k does work editing the wiring.c has no affect

i then thought i could just increase my delay by 64 times. This does make it appear to count at the correct rate however my DHT11 humidity sensor doesn't work.

Where is your code?

Are we supposed to guess what you have done, and why it doesn't work? See point 6 on the page I linked to.

Quote
and want to set the 0 timer to 62.5k

62.5k what? 62.5 kHz? 62.5 k milliseconds? microseconds? nanoseconds?
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is just some simple code as example

now as mentioned before, everything works fine when set to the default settings but soon as as i change the timer 0 to 1 and do the below it the DHT11 doesn't work.

according to the link i posted i should change the wiring.c code to get it to count at the correct speed however changing this files does nothing. ( im not to worried about that as long as the DHT11 will work)

interestingly i've change the second timer to "1" and while it works after a while it starts giving incorrect information back 

Code:
#define DHT11_PIN 0      // ADC0 humididty
long fixtimer;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif

uint8_t bell[8]  = {0x4,0xe,0xe,0xe,0x1f,0x0,0x4};
uint8_t note[8]  = {0x2,0x3,0x2,0xe,0x1e,0xc,0x0};
uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0};
uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0};
uint8_t duck[8]  = {0x0,0xc,0x1d,0xf,0xf,0x6,0x0};
uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0};
uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0};
uint8_t retarrow[8] = { 0x1,0x1,0x5,0x9,0x1f,0x8,0x4};
 
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

byte read_dht11_dat()// humididty
{
  byte i = 0;
  byte result=0;
  for(i=0; i< 8; i++)
  {
    while(!(PINC & _BV(DHT11_PIN)));  // wait for 50us
    delayMicroseconds((30 * fixtimer));
    if(PINC & _BV(DHT11_PIN))
      result |=(1<<(7-i));
    while((PINC & _BV(DHT11_PIN)));  // wait '1' finish
    }
    return result;
}


void setup()
{
  TCCR0B = TCCR0B & 0b11111000 | 1;
 
  fixtimer = 64;
   DDRC |= _BV(DHT11_PIN); // Hum
  PORTC |= _BV(DHT11_PIN); //Hum
  Serial.begin(9600); //hum
  Serial.println("Ready"); //hum
 
//  Serial.begin(57600);
  lcd.init();                      // initialize the lcd
  lcd.backlight();
 
  lcd.createChar(0, bell);
  lcd.createChar(1, note);
  lcd.createChar(2, clock);
  lcd.createChar(3, heart);
  lcd.createChar(4, duck);
  lcd.createChar(5, check);
  lcd.createChar(6, cross);
  lcd.createChar(7, retarrow);
  lcd.home();
 
  lcd.setCursor(0, 0);
  for(int i = 0;i < 20; i++)  lcd.printByte(6);
  lcd.setCursor(0, 1);
  lcd.printByte(6);
  lcd.print("   Hello world    ");
  lcd.printByte(6);
  lcd.setCursor(0, 2);
  lcd.printByte(6);
  lcd.print("  i ");
  lcd.printByte(3);
  lcd.print(" Adele   !   ");
  lcd.printByte(6);
  lcd.setCursor(0, 3);
  for(int i = 0;i < 20; i++)  lcd.printByte(6);
//  lcd.clear();

}

void loop()
{
  byte dht11_dat[5];
  byte dht11_in;
  byte i;// start condition
// 1. pull-down i/o pin from 18ms
  PORTC &= ~_BV(DHT11_PIN);
  delay((18 * fixtimer));
  PORTC |= _BV(DHT11_PIN);
  delayMicroseconds((40 * fixtimer));
  DDRC &= ~_BV(DHT11_PIN);
  delayMicroseconds((40 * fixtimer));
 
  dht11_in = PINC & _BV(DHT11_PIN);
  if(dht11_in)
  {
    Serial.println("dht11 start condition 1 not met");
    return;
  }
  delayMicroseconds((80 * fixtimer));
  dht11_in = PINC & _BV(DHT11_PIN);
  if(!dht11_in)
  {
    Serial.println("dht11 start condition 2 not met");
    return;
  }
 
  delayMicroseconds((80 * fixtimer));// now ready for data reception
  for (i=0; i<5; i++)
    dht11_dat[i] = read_dht11_dat();
  DDRC |= _BV(DHT11_PIN);
  PORTC |= _BV(DHT11_PIN);
  byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];// check check_sum
  if(dht11_dat[4]!= dht11_check_sum)
  {
    Serial.println("DHT11 checksum error");
  }
  lcd.setCursor(0, 0);
  lcd.print(dht11_dat[0], DEC);
  lcd.setCursor(0, 2);
  lcd.print(dht11_dat[2], DEC);
  Serial.print("Current humdity = ");
  Serial.print(dht11_dat[0], DEC);
  Serial.print(".");
  Serial.print(dht11_dat[1], DEC);
  Serial.print("%  ");
  Serial.print("temperature = ");
  Serial.print(dht11_dat[2], DEC);
  Serial.print(".");
  Serial.print(dht11_dat[3], DEC);
  Serial.println("C  ");
  delay((2000 * fixtimer));
}


Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18764
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i have a NANO and want to set the 0 timer to 62.5k

Why do you want/need to to this?


Quote
While changing it to 62.5k does work editing the wiring.c has no affect

What editing?

Quote
Code:
 PORTC &= ~_BV(DHT11_PIN);

What is wrong with:

Code:
digitalWrite (A0, LOW);

Quote
Code:
 DDRC &= ~_BV(DHT11_PIN);

What is wrong with:

Code:
pinMode  (A0, INPUT);

This sort of stuff is hard to read, for no purpose:

Code:
 DDRC |= _BV(DHT11_PIN); // Hum
  PORTC |= _BV(DHT11_PIN); //Hum

Just say:

Code:
pinMode (SENSORPIN, OUTPUT);
digitalWrite (SENSORPIN, HIGH);

Why force people to reach for the datasheet, just to check you have the right bits and ports? Hopefully the sensor is plugged into A0 but you don't mention that.

The page you linked to mentions a library. Why don't you just use that?



By setting the prescaler to 1 you change the rate at which the Timer0 interrupt fires to be 64 times as often. Normally it fires every 1.024 mS and updates the counter used in millis() and micros(). Now it will fire every 1.024mS/64, that is 16 uS.

The interrupt service routine itself takes around 3 uS to fire, then it has to do stuff, and then another 3 uS to wrap up. Out of 16 uS it doesn't have much time. Amongst other things, I think that having these almost constant interrupts is going to throw out what looks like timing-dependent code.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Right i'll start from the beginning myabe that will help. I have already created a dual channel Temperature controller.

The whole thing controls my Fans and TEC's which ultimately cools my computer. both sides of the TEC are water cooled ( hot and cold sides )

The first channel requires a target temp and the Arduino reads the zx-thermometer, which is measuring the TEC's HOT side water temp. The arduino will increase the duty cycle of the Fans to keep the water at the target temp.

The same is true for the cold side of the TEC however i have a dht11 which reads the ambient temp and humidity. The arduino then works out the dew point and sets the Target temp on the fly at 1c above dew point. The Arduino then changes the duty cycle of TEC's to keep the cold side water at the Target temp.

Now all of the above works just fine.

Because of efficiency gains at low pwm duty cycles when dealing with TEC's i want to convert the PWM to an analogue out put. To do this im using a Low pass filter. The TEC's pass 600watts. so the resistance of the resistors in the low pass filter is very low 0.135ohms. otherwise their is to much heat generated and to much voltage loss. because the arduino only switch at 1khz this means i have to have very large capacitance to reduce the ripple. approximately 164,000uf which of coarse is very large and expensive.

If i was able to run the arduino at 62.5khz it would then require 1/62 the amount of capacitance for the same ripple. which is what im trying to achieve. 

http://arduino.cc/playground/Main/TimerPWMCheatsheet

Now according to this post i can run the Arduino at 62.5khz  by adding this line to the start up
TCCR0B = TCCR0B & 0b11111000 | 1;

As far as i can tell making the above does increase it's frequency. However as the link says the arduino now counts to fast and the DHT no longer works.

According to the link you can fix the incorrect timing by changing this " #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(PRESCALE_FACTOR* 256))" line in this file "hardware\arduino\cores\arduino\wiring.c"

However this is not the case changing the wiring.c has no affect on how fast the Arduino seems to count.

Now i thought to my self this is no big deal i can just take the stock times and multiply them ( fixtimer in my code) by 64 to get back to the correct actual time. However this also does not work.

Now since changing timer 0 affects the arduinos timings as part of my testing i thought i could leave timer 0 at the stock timings and change timer 2. Now this wouldn't give me 62khz it would give me 31khz but that's still 32 times faster than the 1khz i have now. While running timer 2 at 1 the DHT11 works fine for a while but about 10 minutes later it starts giving incorrect numbers.

What does work is 4khz on timer 2 but no faster than that. 

Now the Code i posted clearly isn't my full project as part of my testing i stripped it back to the basics.

The code i posted i wrote NONE of it. When i bought the LCD and DHT from robotshop.com they came with code which i copied and pasted into my project.

So your comments on the code is actually a comment on code i didn't write and have NO idea why it is the way it is. Soo i have no idea what's wrong with it. especially since it all works with the stock timers 
         
Thanks for your valuable time
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18764
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, well there are three timers. You might be better off doing analogWrite to one that is not on Timer 0. Then all those problems go away.

Only D5 and D6 are on Timer0.

Quote
Now since changing timer 0 affects the arduinos timings as part of my testing i thought i could leave timer 0 at the stock timings and change timer 2. Now this wouldn't give me 62khz it would give me 31khz but that's still 32 times faster than the 1khz i have now.

Ah, why?

Quote
While running timer 2 at 1 the DHT11 works fine for a while but about 10 minutes later it starts giving incorrect numbers.

Well, why is that? What incorrect numbers?
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

"Ah, why?"
why what?

"Well, why is that? What incorrect numbers?"
it stops producing the correct humidity number
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18764
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not really interested in playing 20 questions with you, maybe someone else can help better.

You said:

Quote
Now since changing timer 0 affects the arduinos timings as part of my testing i thought i could leave timer 0 at the stock timings and change timer 2. Now this wouldn't give me 62khz it would give me 31khz but that's still 32 times faster than the 1khz i have now.

I said why? (Why does it not give 62 kHz?)

You reply:

Quote
why what?



Then you say:

Quote
i could leave timer 0 at the stock timings and change timer 2

Well, show this code, the code that does not give you 62 KHz.



You say:

Quote
it starts giving incorrect numbers

I say:

Quote
What incorrect numbers?

You reply:

Quote
it stops producing the correct humidity number

Yes, I know the incorrect number is not the correct number.

You need to put in debugging prints. You need to show your code, not just say "I tried X and it didn't work". If the numbers are incorrect you need to show the incorrect number (copy and paste) and what you think the correct numbers are, and why.
Logged


Pages: [1]   Go Up
Jump to: