CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

7 segment time
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kamillas



Joined: 24 Oct 2011
Posts: 50

View user's profile Send private message

7 segment time
PostPosted: Fri Feb 17, 2012 4:09 pm     Reply with quote

Hello, I made a circuit that calculates the temperature using DS18B20 and two 7-segment. But I found a problem in the multiplexing (time). With a time of 50 ms, the segment connected to pin D2 will stay on, but the segment connected with D3 appears occasionally. I want the number two in both segments to appear at the same time. Aide me please.
Code:

#include <16F877A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=12000000)

#include <onewire.c>

#include <18b20.c>

int  tab[10] = {0xbF,0x6,0x5b,0x4f,0x66,0x6D,0x7D,0x7,0x7f,0x6F};
byte temp1 , temp2 ;
int temperature ;
int i , j ;

void main()
{
aa:
temperature = ds1820_read();
   
temp1 = temperature %10;
temp2 = temperature /10;

i=500 ;
if (i=!0){

         OUTPUT_d(0b00000100) ;
         OUTPUT_b(tab[temp1]);     

  delay_ms( 50 );
{}

        OUTPUT_d(0b00001000) ;
         OUTPUT_b(tab[temp2]);       
  delay_ms( 50);
{}

       i--;
      if (i==0)
     
      goto aa;
      }
}


http://www.hostingpics.net/viewer.php?id=414689DSC02491.jpg

http://www.hostingpics.net/viewer.php?id=464604DSC02490.jpg
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Feb 17, 2012 4:23 pm     Reply with quote

There are so many things wrong it is difficult to know where to start....

First, what can an int (i) hold?. Can it hold '500'?.
Second, try to use some logic in your code layout. Indent stuff when it is in a loop or code section, don't use random indenting, makes the code difficult for you (and everyone else) to follow, and encourages errors....
Third avoid goto, unless you have good reason. Your loop would be much easier handled by a while or do.
Fourth, what happens at the end of your code, when i does _not_ equal zero?. This ties with #3.
Fifth, what size number does ds1820_read return?. Is this going to fit in your 'temperature' variable?.

etc. etc...
kamillas



Joined: 24 Oct 2011
Posts: 50

View user's profile Send private message

PostPosted: Fri Feb 17, 2012 5:16 pm     Reply with quote

The temp is selected for the segment that is still on. I want another explanation. Thank you for your effort but I did not understand, sorry.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Feb 17, 2012 5:42 pm     Reply with quote

Like Ttelmah says its a wonder anything works at all.

Your layout is absolutely horrendous.
I thought goto's were banned last century.
Make your code layout neater so that you and I can follow it easily.
From what I can decipher of your code, the multiplexing rate is almost an order of magnitude too slow.
Your display is going to flicker for several reasons.

Curly brackets {} come in pairs, indent so that a closing bracket appears below its opening bracket.

Present a simple schematic so that we can relate code to hardware.

Mike
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Does this work any better?
PostPosted: Fri Feb 17, 2012 6:03 pm     Reply with quote

Code:
void main()
{
   while (TRUE)
  {
    temperature = ds1820_read();
   
    temp1 = temperature %10;
    temp2 = temperature /10;

    OUTPUT_d(0b00000000);
    OUTPUT_b(tab[temp1]);     
    OUTPUT_d(0b00000100);
    delay_ms(5);

    OUTPUT_d(0b00000000);
    OUTPUT_b(tab[temp2]);       
    OUTPUT_d(0b00001000);
    delay_ms(5);
  }
}
kamillas



Joined: 24 Oct 2011
Posts: 50

View user's profile Send private message

aide
PostPosted: Sat Feb 18, 2012 3:51 am     Reply with quote

thank you, you understand me, if you use this program, my system shows that the "temp2" in segment 2, but I see no temp1 appears in a segment, and this delay is due to "5ms "So the problem, if I want to see the number two at the same time in both segments must be played on time multiplexing, and that is his problem ..
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Feb 18, 2012 4:28 am     Reply with quote

Mike Walne wrote:
I thought goto's were banned last century.


Thankfully not. Goto allow you to implement error handling and exit simply in a complex function.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
kamillas



Joined: 24 Oct 2011
Posts: 50

View user's profile Send private message

PostPosted: Sat Feb 18, 2012 5:09 am     Reply with quote

asmallri wrote:
Mike Walne wrote:
I thought goto's were banned last century.


Thankfully not. Goto allow you to implement error handling and exit simply in a complex function.
I want a clear answer, I want a solution to my problem
Quote:
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat Feb 18, 2012 4:44 pm     Reply with quote

To asmallri on goto's

OK I stretched a point. As a general rule, goto's are a bad idea. They make for poor programming style. With the sole exception of catastophic failure recovery, I've not used one for over quarter of a century. If I've got a loop / sequence, I'm having difficulty getting out of then it's telling me I need to restructure it.

To kamillas

You are not making it easy for us.
We obviously have a translation barrier.
To keep things simple, I will use short sentences.

I don't have 18B20 so can't help with that bit.
I can do LED multiplexing.

I have tried to decipher your code.
I have compiled what I can of your code.
It does appear as though the multiplexing should work.

I am assuming that ds1820_read() returns temperature in Celcius as an integer.

You then calculate temp1 as unit's digit. (Why not call it temp_unit?)
You then calculate temp2 as ten's digit. (Why not call it temp_ten?)

I am assuming that your digit drive is active high.
(i.e. a 1 turns the digit on and a 0 turns it off.)

In both your jpg pictures the TEN's digit IS lit.
In one jpg picture the UNIT's digit is NOT lit.

In your code you:-

(1) Activate D2.
(2) Load segments with UNIT's code.
(3) Wait 50ms.
(4) Activate D3.
(5) Load segments with TEN's code.
(6) Wait 50ms.
(7) loop back to (1)

You complain that D2 IS working and D3 NOT.

It does not make sense!

Surely it's the other way round.

i.e. D3 IS working, and D2 NOT.

I don't have your hardware in front of me.

So I'm relying on your answers to try and help.

I looks to me that you've got a hardware problem.

Maybe a poor connection in your rats nest.

See what happens when you try:

(1) Swapping connections to D2 and D3 at the PIC.
(2) Swapping connections to the common terminals on LEDs.
(3) Moving to different D port pins, and recompile.

If you are really convinced that the problem is sofware try:-

Swapping the order in which you multiplex the drives.

If all else fails try out the code below.


Don't argue.
Don't ask questions.
Just try the code.
Don't tell us it's not answering your question.
But please tell us what you SEE.
Then we can move forward.
Code:


#include <16F877A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=12000000)

int  tab[10] = {0xbF,0x6,0x5b,0x4f,0x66,0x6D,0x7D,0x7,0x7f,0x6F};
byte temp_unit , temp_ten ;
int temperature = 0;
int i ;

void main()
{

  While (TRUE)
  {
    temperature = 0;
    while (temperature < 100 )
    {
      temp_unit = temperature %10;
      temp_ten  = temperature /10;
      i = 0 ;
      while ( i < 100 )
      {
        OUTPUT_d(0b00000000) ;
        OUTPUT_b(tab[temp_unit]) ;     
        OUTPUT_d(0b00000100) ;
        delay_ms( 5 );
           
        OUTPUT_d(0b00000000) ;
        OUTPUT_b(tab[temp_ten]);       
        OUTPUT_d(0b00001000) ;
        delay_ms( 5 );
        i++;
      }
      temperature++;
    }
  }
}

Mike
kamillas



Joined: 24 Oct 2011
Posts: 50

View user's profile Send private message

Thank you M. MIKE WALNE
PostPosted: Sun Feb 19, 2012 5:42 pm     Reply with quote

Really sir, thank you for your very clear answer, but yesterday I found myself what's the problem, the subroutine DS18B20 it really takes a lot of time for reading the temperature. Therefore, I delayed playback by 05 seconds, so the multiplexing worked well, and therefore every 05 seconds, the display in both segment flashes since the program read the temperature that blocks multiplixage.

I really thank you again "M.MIKE", for your great effort, and I wish you that your method of explanation must be generalized in this forum.
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Feb 19, 2012 6:43 pm     Reply with quote

The DS18B20 will take 750ms( that 3/4 of one second) for a 12 bit reading, the default for it.

You can reprogram it for faster results but lose resolution. If you can accept 9 bits, it'll be a lot faster.

Just read the datasheet, it's in there...I read it months ago though.

Since you're only displaying 2 digits ( 20*c, 21*c), you may want to go to 9 bit mode so your display is 'quicker'.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Multiplexing with a timer
PostPosted: Tue Feb 21, 2012 2:58 am     Reply with quote

Glad you got things to work. Thanks for your generous comments.

What made you realise where the problem was?


You do NOT have to stop the display whilst you get data from the temperature sensor.

I do not normally do this sort of thing but I'm making an exception for you.

Try the code below AS IS.

It should count from 0 to 99 at ~2/s then repeat.

When that's OK:-

(1) Remove time delay and temperature test from main().
(2) Put your read temperature sense back into main().
(3) Leave isr as is.
(4) Leave timer setup as is.
(5) I.e. effectively rewrite the WHILE {} loop.

Note:-

(i) Display runs whilst main() reads temperature data.
(ii) Main() spends most of its time in delay_ms(1000) twiddling its thumbs.
(iii) You can SEE code structure at a glance.
(iv) Each closing } bracket is immediately below its opening { bracket.
(v) ALL code between any pair of {} brackets is indented.
(vi) You can view the WHOLE of a routine within a screen, i.e. without scrolling.
(vii) You've been told MOST of this before in YOUR previous topics.
(viii) If a routine / function expands beyond a screen-full, it's time to consider splitting it.
(ix) There is no right way for most programmes, but some are better than others.
(x) You can improve on my code.
(xi) Eg. for more digits I would use either more arrays or pointers
(xii) Coding for compactness, readability, and speed are often different.
(xiii) This list goes on.................
Code:

/*
**************************************************************************************
**  Multiplexes temperature value on two seven segment displays
** 
**  Digits are updated @ ~700Hz in isr
**
**  Main spends time collecting temperature data at its own pace
**
**************************************************************************************
*/

#include <16F877A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=12000000)

// Declare constants & variables
int  tab[10] = {0xbF,0x6,0x5b,0x4f,0x66,0x6D,0x7D,0x7,0x7f,0x6F};   // segment table, symbols 0 - 9
int temperature;
byte temp_unit , temp_ten ;                               // temperature tens & units
int digit;                                              // current active display digit index


// main()
//
// sets up timer0 for interrupts.
//
// in a loop
//   forces temperature value to advance twice per second
//   confirms temperature display multiplex is working
//
// when happy that multiplex is working:-
// remove delay_ms(500).
// replace temperature advance with read_18B20() function.
//

// *****************************************************************************************

void main()
{
  setup_timer_0(RTCC_DIV_16 | RTCC_INTERNAL | RTCC_8_BIT);   // timer 0 interrupts @~700Hz
  enable_interrupts(INT_TIMER0);                           
  enable_interrupts(GLOBAL);

  While (TRUE)
  {
    temperature = 0;
    while (temperature < 100 )
    {
      temp_unit = temperature %10;
      temp_ten  = temperature /10;
      delay_ms( 500 );
      temperature++;
    }
  }
}


// *****************************************************************************************



// timer0 interrupt isr.
//   selects new digit to light.
//   turn last digit off
//   sets new digit segments
//   turn new digit on
//   exit isr

// *****************************************************************************************

#int_timer0
void segment_mux_isr()
{
  digit++;                  // advance to next digit
  digit%=2;                  // reset to 0 if > 1
  if (!digit)               // test for digit 0
  {
    OUTPUT_d(0b00000000) ;       
    OUTPUT_b(tab[temp_unit]) ;   
    OUTPUT_d(0b00000100) ;       // digit 0 is units i.e. 10^0
  }
  else
  {
    OUTPUT_d(0b00000000) ;
    OUTPUT_b(tab[temp_ten]);       
    OUTPUT_d(0b00001000) ;       // digit 1 is tens i.e. 10^1
  } 
}


// *****************************************************************************************


Best wishes

Mike
kamillas



Joined: 24 Oct 2011
Posts: 50

View user's profile Send private message

Good
PostPosted: Tue Feb 21, 2012 5:07 pm     Reply with quote

Hello Mike,

Thank you, so what I understood from your program is that you have made the multiplexing program interruption, so I read_ds18b20 mid function, in the main program.
I also have 4 questions:
1 - what does this function: if (! Digit)?
2- why did you put on the main program temperature = 0?
3 - why in the main pogramme, you mentioned delay_ms (500)?
But this time is useless!
4 - this function: digit%=2, if for example I did: digit%=3 means what?

Thanks
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Feb 21, 2012 8:50 pm     Reply with quote

Kamillas...you've got to read and re-read Mike's test program again...

He was very nice to take the time to cut test code for you, very nice to add comments as to why he did what he did!!

from what I just quickly read...

1) !digit, as the comment /...... says, tests for the '0' digit( units)

2) temperature=0; is the starting value for the variable called temperature.It allows the display to go from 00 to 99. He could have put in 32 , then the display would increments 32,33,34,....99.

3)delay_ms(500) is for us humans to SEE the display,judge if the refresh( update,multiplex,scan) rate is OK or not.You have to read his comments in the preamble !

4) that's a quick and clever test to determine which of the 2 digits( 10s or 1s ) to use to display the data

This version of C is not that hard compared to say Delphi which has 1,000s of functions,keywords, and 'interesting' syntax.I do prefer to cut assembler though as I've always found 'higher level' languages a bit of a 'cheat'. However YOU have to do read,test,observe and try again and again in order to learn.This does not come overnight or in a few short weeks working just a couple hours a day.I've got thousands of hours over the past 20 years of using PIC C and learn new things everyday.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Multiplexing
PostPosted: Wed Feb 22, 2012 3:35 am     Reply with quote

temtronic.

Thank you for doing the comments. We seem to be singing from the same hymn sheet. We're obviously in different time zones. I find it amazing.


kamillas.

Have you tried my code?

If no. Why?

If yes. Did it work?

Mike
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group