Dividing F_CPU and printing on LCD not working

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I am working with Atmega328 microcontroller have defined F_CPU as 8000000 (8Mhz) and below Macro:

#define INSTR_PER_US F_CPU/1000000	// instructions per microsecond

Now, I run the 16 bit timer and read the value; say for example counter value is 25000, I assign it to no_of_ticks.

no_of_ticks = TCNT1; 

If I use lcd_put_int(no_of_ticks) on LCD, it prints 25000.
I also print the value of INSTR_PER_US on LCD. It prints 8

So far, so good. But if I use lcd_put_int(no_of_ticks/INSTR_PER_US), it prints 0.
Any idea why?

If the function for lcd might be of any help, I am using fluery's LCD library and added lcd_put_int(int num)

void lcd_put_int(int num)
/* get integer and print it as string */
{
	char buffer[7];
	itoa(num, buffer, 10);	// convert integer into string (decimal format)
	lcd_puts(buffer);
}/* lcd_put_int */

Any help is greatly appreciated

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are calculating 25000/F_CPU/1000000. What is the value of that expression?

Always, always use parens around any kind of calculation in a #define

#define INSTR_PER_US (F_CPU/1000000)
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bulls Eye!!! Thank you. Just executed and it is working as expected. :)

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Bulls Eye!!! Thank you. Just executed and it is working as expected.

Now, how accurate will your calculation be if F_CPU is not evenly divisible by one million?

(and the mention of 8MHz implies "internal oscillator" to me. That can be some per cent different than the nominal value.)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Now, how accurate will your calculation be if F_CPU is not evenly divisible by one million?

Well, I am not sure. But I am using external 16MHz crystal and the values are ok. But for the sake of testing, I used the internal oscillator which also seems to be ok.

Is there a better way to do this than hard coding the values?

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define INSTR_PER_US (F_CPU/1000000) 
no_of_ticks = TCNT1;
 lcd_put_int(no_of_ticks/INSTR_PER_US):

might become

no_of_ticks = TCNT1;
  lcd_put_int((no_of_ticks*1000000) / F_CPU); // avoid a lot of truncation errors... same result with integer multiples of MHZ
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

#define INSTR_PER_US F_CPU/1000000 // instructions per microsecond

Given that the AVR has 1, 2, 3, 4 (and possibly even more) cycle opcodes how can you define this as "instructions per usecond". I think it would be very difficult indeed to define an exact figure for INSTR_PER_US though I suppose it might average about 1.4 or something? (and at 1MHz the value could be less than 1). It take it you actually mean "cycles per usecond"? (but again, the point for <1MHz holds - below 1MHz the value is fractional).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, yes. I mean cycles_per_us (renamed it in my program also). A little background. I am creating an ultrasonic library for SR04 module. I thought it is easier to put everything in Macros so that it might be simpler if one changes clock from 1MHz to say 16MHz.

I did not think of probability of less than 1MHz while coding :( my bad.

#define CYCLES_PER_US (F_CPU/1000000)// instructions per microsecond
#define CYCLES_PER_MS (F_CPU/1000)		// instructions per millisecond
#define CONVERT_CM ((10000*2)/SPEED_OF_SOUND)
#define TIMER_MAX 65535

I am using F_CPU in result while converting it into cm like:

return ((((overFlowCounter*TIMER_MAX)+no_of_ticks)/CONVERT_CM)/CYCLES_PER_US);

and for checking if it has timed out:

uint32_t max_response_time = (uint32_t) CYCLES_PER_MS * TRIG_TIMEOUT;

Maybe, I need to rewrite the code specifically for particular frequency.

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe somebody might still need this code. Here is the complete code for HC-SR04 ultrasonic sensor for ATmega328P running at 16MHz. sonar.h [code:1] /*! * ******************************************************************************************************** * \file sonar.h * \brief Interfacing HC-SR04 Ultrasonic Sensor Module (Sonar) * * \author : Praveen Kumar * \date : Mar 24, 2014 * Copyright(c) : Praveen Kumar - www.veerobot.com * Description : Interfacing HC-SR04 Ultrasonic Sensor Module (Sonar). * Program is tested on Draco - AVR Development board available at www.veerobot.com which * has an ATmega328P microcontroller. If you replace that with any other * 28 pin AVR microcontroller, be sure to modify registers accordingly. * * LICENSE : Creative Commons Attribution-NonCommercial-ShareAlike * Use this library as long as you credit the author and keep this header in place * * ******************************************************************************************************** */ #ifndef SONAR_H_ #define SONAR_H_ #ifndef F_CPU #define

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

Last Edited: Mon. Sep 8, 2014 - 07:30 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I guess I can add this as a project here. But not sure if this is ok and works well.

Then you most definitely MUST not added it as a project here. People seem to misunderstand the idea of the Project area here (or indeed any code repository on the internet). It's not just for posting code the first time it looks like something might possibly work a bit.

Consider the "consumer". There are beginners out on the internet looking for pre-made code solutions for all sorts of things. They want to download and use something they can trust. They get VERY disheartened when they down load five different things that all purport to do the same thing (like driving an LCD or whatever) and, for whatever reason, they are the first person to find the first 50 bugs in the code and none of them work.

So the consumer a big favour and only post extremely well tried and tested code that has been proven in many scenarios - if you do you may become famous like Peter Fleury or Pascal Stang or Peter Dannegger or someone (bet I spelled that wrong!).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That was the basic idea of creating this library. I did download many libraries and codes here and few other places for sonar. Either they were buggy, not beginner friendly, were not customizable, or part of a bigger project and unhelpful.

I did my best to make this cover all above mentioned. But yes, not tested thoroughly yet. Maybe others can use and let know their comments. Since it is just a matter of changing pin names, should be easy to connect and test. Thanks for your suggestions.

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 

#ifndef F_CPU
   #define F_CPU 16000000UL      // CPU Frequency
#endif

should be rewritten as:

#ifndef F_CPU
   #define F_CPU 16000000UL      // CPU Frequency
#endif
#include 

(delay.h needs F_CPU to compute accurate delays; else, the default value is 1E6 Hz, which would lead to unconsistancies... difficult to test with one Xal..)

Edited : do you need
#include "lib/lcd.h" (and what would happen if someone wants to use your library with anther LCD library)?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
(delay.h needs F_CPU to compute accurate delays; else, the default value is 1E6 Hz, which would lead to unconsistancies...

Thanks. Will change it.
Quote:
difficult to test with one Xal..)
Crystal not required to test. It works straight away with internal 1Mhz crystal with changing only F_CPU.
Quote:
#include "lib/lcd.h" (and what would happen if someone wants to use your library with anther LCD library)?

Not required. It is not used anywhere in the program. I had added it for debugging. Will edit the code above and remove it.

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

https://www.avrfreaks.net/index.p...
SIGNAL should become ISR... in SIGNAL(TIMER1_OVF_vect){ // Timer1 overflow interrupt
(if it is deprecated, some day/month/year compiler wonot support it Annie More)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
SIGNAL should become ISR... in SIGNAL(TIMER1_OVF_vect){ // Timer1 overflow interrupt
Modified in the original code. Thanks :)

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see two other issues:
a) you reinit sonar every time (is it necessary?)
b) you defined sound speed as a constant at 20 C. Monitoring water levels in open air in Europe can occur in temperatures ranging between (for Paris) between -10 C end 35 C -3% error- and incertainties in low levels can be annoying in summer droughts, where level is far from the sensor). Maybe provision should be made for an user-written (depends on the presnce and kind of sensor) temperture information...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
a) you reinit sonar every time (is it necessary?)

Depends I guess. The main program can call init_sonar(); and it is all done. For a beginner, all s/he has to do is call range_in_cm=read_sonar(); and it auto-magically does everything in the background. Not sure if it affects the working of sonar in any way. I have kept the module on for 24 hours now and it seems to be working fine without any issues. If it does cause an issue, will pull the line out to the main program.

Quote:
b) you defined sound speed as a constant at 20 C
This would make it a lot of hyper-physics, v = 331 m/s + (0.6 m/s/C)•T, where T is......

#define SPEED_OF_SOUND   343

This gives the provision to users to calculate the speed of sound outside the code and enter it here. I guess it is good to keep it simple.

On an other note, I am working on a project which has a temperature and humidity sensor attached to the board and that calculates speed of sound depending on the environment.

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Clawson wrote:

Quote:
Then you most definitely MUST not added it as a project here

There is a grey zone between
a)softwares being debugged in this forum
and
c) fully tested softwares which can go in a project section.
Someone who writes software for himself can achieve (maybe with some help) something which "works" for him, but has no time (even if a compiler changes) or -incl- no testing methods (having something working for 72 hrs on a given mcu, with a given set of interrupts, seems poor empirical testing and I cannot figure out better methods)to make this software safely avalaible and usable by others... (in the late 80-s, some "professional" softwares were categorized as "only their author can run them to day" -and it was annoying when the author was ill, as they were interesting/necessary-...)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is a grey zone between
a)softwares being debugged in this forum
and
c) fully tested softwares which can go in a project section

 

ok. I get the point. For now, let it be as is....

Robot building is all about sharing & learning
-----------------------------------
www.robotplatform.com