• AVR Freaks

Hot!Assembly Code to Read Humidity Sensor

Page: << < ..67 > Showing page 6 of 7
Author
delfindelfin
Super Member
  • Total Posts : 300
  • Reward points : 0
  • Joined: 2017/01/19 12:32:58
  • Location: Mexico
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/04 19:21:22 (permalink)
0
How about this?
 

 
 
 
void read_humidity_sensor()
{
 
    int j;

    humid = 0 ;
    temp = 0 ;
    checksum = 0 ;

    __delay_ms(0.08); // DHT22 Responds Low for 80 uS
    __delay_ms(0.08); // DHT22 Responds High for 80 uS

    for(j=0;j<40;j+=1)
    {

        while (PORTCbits.RC2 != 1); // wait until RC2 is high

        __delay_ms(0.03); // Wait 30 uS to see if data bit is High and Low

        if(j<16){
            if (PORTCbits.RC2 == 1){ // Select Data Humidity
                humid = humid + (1 << (16 - j) );
            }
        }
        else if(j >= 16 && j <= 32){ // Select Data Temperature
            if (PORTCbits.RC2 == 1){
                temp = temp + (1 << (16 - j) );
            }
        }
        else{
            if (PORTCbits.RC2 == 1){ // Select Data Checksum
                checksum = checksum + (1 << (8 - j) );
            }
         }

        while (PORTCbits.RC2 != 0); // Wait until RC2 is Low

     }

}
 
 
 

post edited by delfindelfin - 2019/04/04 20:13:02

MPLAB X IDE v5.05
XC8 2.00
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/04 19:38:32 (permalink)
+1 (1)
Nearly.

This line:
        while (PORTCbits.RC2 != 0); // Wait until RC2 is Low
should be immediately before this line
        while (PORTCbits.RC2 != 1); // wait until RC2 is high
 
which is precisely what I told you to do back in post# 79

Nearly there...
delfindelfin
Super Member
  • Total Posts : 300
  • Reward points : 0
  • Joined: 2017/01/19 12:32:58
  • Location: Mexico
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/04 20:14:54 (permalink)
0
Oh I see. But I think there's still something wrong in the code since it seems that the function read_humidity_sensor() behaves like an infinite loop

MPLAB X IDE v5.05
XC8 2.00
PStechPaul
Super Member
  • Total Posts : 2293
  • Reward points : 0
  • Joined: 2006/06/27 16:11:32
  • Location: Cockeysville, MD, USA
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/04 21:27:14 (permalink)
+1 (1)
I don't think this delay macro accepts a floating point argument:
__delay_ms(0.03);

Instead, try:
__delay_us(30);

Also, I think you may have a misplaced "{" or "}".

 
PStechPaul
Super Member
  • Total Posts : 2293
  • Reward points : 0
  • Joined: 2006/06/27 16:11:32
  • Location: Cockeysville, MD, USA
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/04 21:27:14 (permalink)
0
I don't think this delay macro accepts a floating point argument:
__delay_ms(0.03);

Instead, try:
__delay_us(30);

Also, I think you may have a misplaced "{" or "}".

 
pcbbc
Super Member
  • Total Posts : 1098
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/04 21:38:53 (permalink)
+1 (1)
Most likely...
Your delays are too long, so you are missing some edges.
Or there aren’t 40 bits arriving.
Or your code is too slow.

Some observations...
Try sizing your variables correctly. My guess is (based on j) you have everything defined as int. this is very wasteful on an 8 bit processor - use unsigned char (or uint8_t) wherever you can get away with it.

Your shifts are also non-optimal for an 8 bit device which does not have a multi-bit shift machine instruction. All those shifts require the compiler to insert a loop to generate your value to add:
int temp = 1;
for (i=0; i < N-1; i++) temp <<= 1;


Assuming humid and temp are unsigned 16 bit (uint16_t) and checksum is unsigned 8 bit (uint8_t) something like the following will be quicker:
if (j<16) {
humid >>= 1;
if (PORTCbits.RC2 == 1) humid |= 0x8000;
} else if (j<32) {
temp >>= 1;
if (PORTCbits.RC2 == 1) temp |= 0x8000;
} else {
checksum >>= 1;
if (PORTCbits.RC2 == 1) temp |= 0x80;
}
That’s better because a single bit shifts can be translated directly to machine instructions.


This line: else if(j >= 16 && j <= 32)
I think has an out by one error on the last bit, as it handles 17 bits (<=32) and not 16 bits (<32).
Also the test against >=16 is redundant here, as that case has already been handled by the first if j < 16 condition.
pcbbc
Super Member
  • Total Posts : 1098
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/04 21:54:03 (permalink)
+1 (1)
Edit: Should of course be...
checksum >>= 1;
if (PORTCbits.RC2 == 1) checksum |= 0x80;

But flipping forum firewall won’t let me edit my original post.
1and0
Access is Denied
  • Total Posts : 9293
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 07:02:59 (permalink)
0
PStechPaul
I don't think this delay macro accepts a floating point argument:
__delay_ms(0.03);

Instead, try:
__delay_us(30);

 

The delay macros can accept a floating point decimal number. ;)
1and0
Access is Denied
  • Total Posts : 9293
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 07:05:20 (permalink)
0
pcbbc
Edit: Should of course be...
checksum >>= 1;
if (PORTCbits.RC2 == 1) checksum |= 0x80;

From what I gathered, I think the data comes in most significant bit first, not least significant bit.
1and0
Access is Denied
  • Total Posts : 9293
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 07:11:08 (permalink)
0
delfindelfin
How about this?
for(j=0;j<40;j+=1)
{
// snipped
            if (PORTCbits.RC2 == 1){ // Select Data Humidity
                humid = humid + (1 << (16 - j) );
            }
        }
        else if(j >= 16 && j <= 32){ // Select Data Temperature
            if (PORTCbits.RC2 == 1){
                temp = temp + (1 << (16 - j) );
            }
        }
        else{
            if (PORTCbits.RC2 == 1){ // Select Data Checksum
                checksum = checksum + (1 << (8 - j) );
            }


For humidity, (16 - j) is off by one bit. For temperature and checksum, (16 - j) and (8 - j) are negative values. Anyway, as others have said, that is a very inefficient way to shift in bits.
1and0
Access is Denied
  • Total Posts : 9293
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 07:14:59 (permalink)
+1 (1)
delfindelfin
Oh I see. But I think there's still something wrong in the code since it seems that the function read_humidity_sensor() behaves like an infinite loop

You need to take care of cases where the sensor is not responding or not connected correctly. That is, a timeout for the waiting loops.
delfindelfin
Super Member
  • Total Posts : 300
  • Reward points : 0
  • Joined: 2017/01/19 12:32:58
  • Location: Mexico
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 10:02:41 (permalink)
0
Is it ok to define j as unsigned char?, because it ranges from 0 to 40. I tought that characters should only consist of one ASCII element

MPLAB X IDE v5.05
XC8 2.00
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3122
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 10:25:05 (permalink)
-1 (1)
Check post #54 and post #55 where I posted C code to read from these sensors.

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
delfindelfin
Super Member
  • Total Posts : 300
  • Reward points : 0
  • Joined: 2017/01/19 12:32:58
  • Location: Mexico
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 10:34:36 (permalink)
0
Gort2015
Check post #54 and post #55 where I posted C code to read from these sensors.




It looks very different from what I am trying to get. I see that you are using arrays again

MPLAB X IDE v5.05
XC8 2.00
delfindelfin
Super Member
  • Total Posts : 300
  • Reward points : 0
  • Joined: 2017/01/19 12:32:58
  • Location: Mexico
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 10:46:04 (permalink)
0
The line that is causing conflict is this one:
 

while (PORTCbits.RC2 != 0);  // Wait until RC2 is Low   

post edited by delfindelfin - 2019/04/05 11:02:14

MPLAB X IDE v5.05
XC8 2.00
pcbbc
Super Member
  • Total Posts : 1098
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 10:56:34 (permalink)
+2 (2)
delfindelfinIs it ok to define j as unsigned char?, because it ranges from 0 to 40. I tought that characters should only consist of one ASCII element
C really doesn’t have a concept of a character type.

Although it is called “char” it is just a byte, and you can do any maths operations on it you like. Hence the signed/unsigned prefix. So either -128 to +127 or 0 to 255.

So if you are conceptually using it to represent a single digit character, sure it will have a value 0x30 to 0x39 which is one of the ASCII characters ‘0’ through ‘9’.
Or if you are using to represent a number, it can have a value 0 (0x00) through 255 (0xFF).
Which it is is entirely down to you; the compiler and the program code do not make any distinction whatsoever.

But if it helps you differentiate in your own mind, include stdint.h, and then you will have access to:
int8_t
int16_t
int32_t
int64_t
uint8_t
uint16_t
uint32_t
uint64_t

The advantage of these types is they are known width on a platform. Int may be 2 or 4 bytes depending on implementation, so using the above makes your code both more readable (we know what is a character and what is a byte) and also more portable.

Use char for character data, and int#_t/uint#_t for everything else, sized according to the maximum value you require.

And yes, I was wrong about my shift order in my previous post. Sorry.
If data come MSB first you need to shift in the opposite direction and OR a 1 into the LSB:
if (j<16) {
humid <<= 1;
if (PORTCbits.RC2 == 1) humid |= 1;
} else if (j<32) {
temp <<= 1;
if (PORTCbits.RC2 == 1) temp |= 1;
} else {
checksum <<= 1;
if (PORTCbits.RC2 == 1) checksum |= 1;
}
mbrowning
Just a Member
  • Total Posts : 1423
  • Reward points : 0
  • Joined: 2005/03/16 14:32:56
  • Location: Melbourne, FL
  • Status: online
Re: Assembly Code to Read Humidity Sensor 2019/04/05 11:15:57 (permalink)
0
pcbbcInt may be 2 or 4 bytes depending on implementation
or even 1 byte on some silly compilers.



Oh well - there's always next year
mlp
boots too small
  • Total Posts : 763
  • Reward points : 0
  • Joined: 2012/09/10 15:12:07
  • Location: previously Microchip XC8 team
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 11:41:09 (permalink)
0
mbrowning
pcbbcInt may be 2 or 4 bytes depending on implementation
or even 1 byte on some silly compilers.

Even on some not-so-silly compilers.
In C, a "byte" is defined as "whatever size a char is", and on machines which can access memory only in 16-bit chunks or larger it's possible for a standard-conforming C compiler to have sizeof(int) == 1 (e.g. on some Cray supercomputers everything was 64 bits wide).

Mark (this opinion available for hire)
delfindelfin
Super Member
  • Total Posts : 300
  • Reward points : 0
  • Joined: 2017/01/19 12:32:58
  • Location: Mexico
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 15:24:21 (permalink)
0
But this line of code is causing problems:
 

 
 
 
while (PORTCbits.RC2 != 0);  // Wait until RC2 is Low   
 
 
 

 
When I comment it there is no infinite loop. It never detects RC2 as Low, or I don't know but it interferes with the LCD by not displaying anything
post edited by delfindelfin - 2019/04/05 15:40:08

MPLAB X IDE v5.05
XC8 2.00
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Assembly Code to Read Humidity Sensor 2019/04/05 15:51:51 (permalink)
0
delfindelfin
But this line of code is causing problems:
 
while (PORTCbits.RC2 != 0);  // Wait until RC2 is Low   

 

That means your sensor is never responding.
As someone mentioned a few posts ago, it would be a good idea to add a timeout to detect if this happens.
That means counting loops, or using a timer interrupt to measure how long you have been waiting.
 
However, that's just to detect that something has gone wrong, it doesn't explain why your sensor is not responding at all.
 
 

Nearly there...
Page: << < ..67 > Showing page 6 of 7
Jump to:
© 2019 APG vNext Commercial Version 4.5