• AVR Freaks

AnsweredHot!Guidance on 433MHz PIC16F Receiver Project

Page: < 123 > Showing page 2 of 3
Author
pcbbc
Super Member
  • Total Posts : 1373
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/11 05:46:34 (permalink)
0
Both the first and third ones are wrong because you just cannot use || and && like that to test if a variable is equal to one of a number of different alternatives.
 
if (value != (1 || 2))

Does NOT test if the variable value is some value other than 1 or 2.
 
It evaluates "1" as a boolean => true
Then evaluates "2" as a boolean => true (Anything non-zero is true in C).
Next it does the || operator "true OR true" => true (a true result is 1 in C).
Finally it tests "value != 1" to get a result for the if logic.
#21
btommo
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2017/07/07 02:59:33
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/11 07:01:27 (permalink)
0

 
void DATAEE_WriteBytes(uint8_t bAdd, uint32_t bData, uint8_t bSize)
{
unsigned int i;
for(i = 0; i < bSize; i++)
{
DATAEE_WriteByte(uint8_t bAdd, (uint8_t*)&bData);
bData >>= 8; //shift to store next byte
bAdd +=1; //go to next address
}
}

 
Does this look to be correct for the write bytes function? Wasn't sure if I understood correctly about the whole saving first byte, then second and lastly third.
 
I think i'll have to save multiple remote codes (as spares) possibly read and stored into an array/look up table on start up? do you have any advice on how to do this efficiently that all the remotes can be checked by increment one variable? rather than having remote1,remote2,remote3 etc.
post edited by btommo - 2019/07/11 07:13:04
#22
pcbbc
Super Member
  • Total Posts : 1373
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/11 07:52:46 (permalink)
+1 (1)
That would be a way to do it, but it is pointless passing in a size if the data is always uint32_t.  We know a uint32_t is a fixed size (4 bytes).
DATAEE_WriteByte(uint8_t bAdd, (uint8_t*)&bData);

I think you got mixed up with the function call I posted earlier.
Your first parameter is invalid (what is the meaning of the uint8_t prefixing the variable bAdd?)
For your second parameter I've no idea why you are using pointers here.  (uint8_t)bData would get you the low order byte, and then your code shifts by 8 to get the next byte.
 
void DATAEE_WriteUInt32(uint8_t bAdd, uint32_t bData)
{
    uint8_t i;
    for(i = 0; i < sizeof(bData); i++)
    {
        DATAEE_WriteByte(bAdd, (uint8_t)bData);
        bData >>= 8; //shift to store next byte
        bAdd += 1; //go to next address
    }
}

 
But a more useful routine might be:
void DATAEE_WriteByte(uint8_t address, uint8_t byte);

void DATAEE_WriteBytes(uint8_t bAdd, uint8_t* pbData, uint8_t bSize)
{
    do
    {
        DATAEE_WriteByte(bAdd, *pbData);
        bAdd++;
        pbData++;
    }
    while (--bSize);
}

void main(void) {
    DATAEE_WriteBytes(0, (uint8_t*)&remote_code, sizeof(remote_code));
}
This routine can write any sequence of bytes, rather than being restricted to 4 byte integers.
 
Granted this approach it does assume the byte order of the CPU (big vs little endian) that is doing the storing.  In reality, as we are storing in the PIC internal EEPROM and won't be transferring that data to another device with a different CPU endianess, that is of little consequence.
#23
btommo
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2017/07/07 02:59:33
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/12 04:24:55 (permalink)
0
I think I did get mixed up, I didn't fully understand pointers as it is also new to me but after doing some reading I think I understand;pdData = (uint8_t*)&remote_code    store address of remote_code in pointer variable pbData*pdData is the data at that addresspbData++ goes to next address. Is it the LSB that's written first or MSB?i.e big endian or little endian (to me it sounds big endian) to determine which order I read back data. I also wrote a read function based on your write function;
void DATAEE_ReadBytes(uint8_t bAdd, uint8_t bSize)
{
    do
    {
        DATAEE_ReadByte(bAdd);
        bAdd++; //next address
    }
    while (--bSize);
}
 I'm still wondering if I would have to have only a finite amount of remotes to write/read eeprom addresses for each remote and have a very busy ccp interrupt checking each remote individually; remote1, remote2 etc or if there is a way for an array with a counter incremented to check through it.
post edited by btommo - 2019/07/13 04:26:48
#24
btommo
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2017/07/07 02:59:33
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 02:50:37 (permalink)
0
I am having an issue with reading data back from eeprom and placing it into a uint32_t remote2, below is the code for initializing this remotes variable;
/**
  Generated Main Source File

  Company:
    Microchip Technology Inc.

  File Name:
    main.c

  Summary:
    This is the main file generated using PIC10 / PIC12 / PIC16 / PIC18 MCUs

  Description:
    This header file provides implementations for driver APIs for all modules selected in the GUI.
    Generation Information :
        Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.76
        Device : PIC16F1823
        Driver Version : 2.00
*/
//------------------------------------------------------------------------------
//Includes
//------------------------------------------------------------------------------
#include <xc.h>
#include <stdint.h>
#include <stdbool.h> 
#include "mcc_generated_files/mcc.h"



__EEPROM_DATA(0xc1, 0xf4, 0xcf, 0x00, 0xff, 0xff, 0xff, 0xff);
//------------------------------------------------------------------------------
// Routines
//------------------------------------------------------------------------------
int swap_Endian(int number)
{
    int byte0, byte1, byte2, byte3;
    byte0 = (number & 0x000000FF) >> 0;
    byte1 = (number & 0x0000FF00) >> 8;
    byte2 = (number & 0x00FF0000) >> 16;
    byte3 = (number & 0xFF000000) >> 24;
    return ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | (byte3 << 0));
}

void Initialize_Remotes(void)
{
    remote2 = DATAEE_ReadBytes(0x00,sizeof(remote2));
    remote2 = swap_Endian(remote2);
    remote2 <<= 1;
    
}
/*
                         Main application
 */
void main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    Initialize_Remotes();

    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:

    // Enable the Global Interrupts
    INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();

    while (1)
    {
        //Add your application code
    }
}
/**
 End of File
*/

 
I initialise remote2 to 0x00FFFFFF in mcc.h, below is the code for DATAEE_ReadBytes();
 
uint32_t DATAEE_ReadBytes(uint8_t bAdd, uint8_t bSize)
{
    uint32_t number;
    do
    {
        number = DATAEE_ReadByte(bAdd);
        number <<= 8;
        bAdd++; //next address
    }
    while (--bSize);
    return number;
}

Before ReadBytes function remote2 = 0x00FFFFFF, after ReadBytes function remote2=0x00000000.
 
I know pcbbc that I'm taking the LSB as a low stop bit for now as I'm working with known values to get the programming remotes feature working.
 
The bytes written to eeprom on start up are know values to the remote2's bytes;
 
11001111 = 0xCF
11110100 = 0xF4
11000001 = 0xC1
 
 
post edited by btommo - 2019/07/15 02:53:41
#25
ric
Super Member
  • Total Posts : 24270
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 03:05:44 (permalink)
0
Why do you need "swap_Endian()" at all?
This version won't work. "int" is a 16 bit signed variable in XC8. You are trying to use it as an unsigned 32 bit variable.

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#26
pcbbc
Super Member
  • Total Posts : 1373
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 03:15:59 (permalink)
0
btommoI didn't fully understand pointers

Pointers are tricky until you finally get your head round them...
 
 
Is it the LSB that's written first or MSB?i.e big endian or little endian (to me it sounds big endian) to determine which order I read back data.

Both your version and mine write LSB first, so little endian.  8-bit PICs would probably be considered a little endian architecture (16 bit registers are generally LSB first).
But it matters not what order you store data in EEPROM so long as you read it back in the same order.
 
// Why are you still passing in bSize, when this routine can ONLY read a uint32_t and you KNOW the size of uint32_t is 4 bytes?
 
uint32_t DATAEE_ReadBytes(uint8_t bAdd, uint8_t bSize)
{
    uint32_t number;
    do
    {
 
        // This line is just overwriting the last byte(s) you read with the new one:
        number = DATAEE_ReadByte(bAdd);
 
        // This line is always shifting left by 8, so the number will always have 0's in the low 8 bits and the last byte of data read in bits 8 through 15:
        number <<= 8;
 
        // You are reading from low to high addresses and the high address byte winds up in the LSB (although then shifted by 8).  This implies BIG endian storage storage:
        bAdd++; //next address
    }
    while (--bSize);
    return number;
}

1. You need to combine the byte you have read with the previous byte(s).  The bitwise OR (|) or add (+) operators are suitable for this.  I would use OR.
2. You need to shift result (to make space) before OR or ADDing in the next byte.
3. You need to read your bytes backwards, or reverse your shift direction and insert new bytes at the high byte.
 
Edit: ric I assume btommo must have editted his post and corrected it, as he is not now using swap_Endian() or int.  There are now a whole load of other things wrong with it...
post edited by pcbbc - 2019/07/15 03:21:08
#27
btommo
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2017/07/07 02:59:33
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 03:22:14 (permalink)
0
When I store the remote values using the write function pcbbc helped me with I thought it would save the values least significant byte first hence the use of swap endian so it is able to compare remote2 against remote_code and why the values are the are saved with __EEPROM_DATA() with the least significant byte saved first.
 
I'll swap to uint32_t for the number used in swap_Endian() to keep all values the same length, I'm having issues with the read byte function at the moment as it seems to return 0x00000000.
 
OK now the read function is kinda working;
uint32_t DATAEE_ReadBytes(uint8_t bAdd, uint8_t bSize)
{
    uint32_t number = 0;
    do
    {
        number += DATAEE_ReadByte(bAdd);
        number <<= 8;
        bAdd++; //next address
    }
    while (--bSize);
    return number;
}

 
resulting in a result of 0xF4CF0000 but this is missing the data in the first address, 0xc1, 
 
Also now the endian swap is kind of working as well;
uint32_t swap_Endian(uint32_t number)
{
    int byte0, byte1, byte2, byte3;
    byte0 = (number & 0x000000FF) >> 0;
    byte1 = (number & 0x0000FF00) >> 8;
    byte2 = (number & 0x00FF0000) >> 16;
    byte3 = (number & 0xFF000000) >> 24;
    return ((byte0 << 24) + (byte1 << 16) + (byte2 << 8) + (byte3 << 0));
}

 
resulting in remote2 0xFFFFCFF4, only issue is it adds 0xFFFF0000 
post edited by btommo - 2019/07/15 03:44:27
#28
ric
Super Member
  • Total Posts : 24270
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 03:56:02 (permalink)
0
You're doing the shift at the wrong point. Change to:
    do
    {
        number <<= 8;
 
        number += DATAEE_ReadByte(bAdd);
        bAdd++; //next address
    }
    while (--bSize);

 
Your swap is failing because you are still using "int" for the working variables.
 
post edited by ric - 2019/07/15 03:57:06

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#29
btommo
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2017/07/07 02:59:33
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 04:05:43 (permalink)
0
Thanks ric, sorted the swap by changing byte0 etc to uint_32, same as remote2, I did notice number was shifting 1 extra time so made bSize-=1 but your was is better. now I get correct result.
#30
pcbbc
Super Member
  • Total Posts : 1373
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 04:25:27 (permalink)
0
A lot easier, more sensible and efficient to read the bytes in the reverse order...
    bAdd += bSize;
    do
    {
        bAdd--; //previous address
 
        number <<= 8;
        number += DATAEE_ReadByte(bAdd);
    }
    while (--bSize);

Then you do not need the complexity of the endian swap at all.
 
Thanks ric, sorted the swap by changing byte0 etc to uint_32, same as remote2, I did notice number was shifting 1 extra time so made bSize-=1

You need to think about why your way would not work.  It's not the number of shifts that's the problem, its the fact that the shift is after the low byte being added in.  That always results in 8 too many shifts and zeros in the bits 7-0.
post edited by pcbbc - 2019/07/15 04:29:28
#31
btommo
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2017/07/07 02:59:33
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 04:34:14 (permalink)
0
I may do that as it would save data and program memory, with the swap code I was at 63% Data and without I have 45%.
#32
pcbbc
Super Member
  • Total Posts : 1373
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 04:44:58 (permalink)
0
btommo
I may do that as it would save data and program memory, with the swap code I was at 63% Data and without I have 45%.

Using the BITWISE OR (|) instead of ADD (+) operator my also save you some space.  Depends on how good the free compiler (assuming that is what you are using) is at optimising.
number |= DATAEE_ReadByte(bAdd);

#33
ric
Super Member
  • Total Posts : 24270
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 04:51:22 (permalink)
0
The four 32 bit scratch variables in that routine would take a bit of data space, but only while that function was running.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#34
pcbbc
Super Member
  • Total Posts : 1373
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 05:42:29 (permalink)
0
ricThe four 32 bit scratch variables in that routine would take a bit of data space, but only while that function was running.

It's more that the OR of a uint8_t into a uint32_t result does not generate any effect (through carry) on the upper 3 bytes of destination like an ADD would.
Therefore XC8 does not generate any code for those bytes (tested in free mode with -O2).
#35
btommo
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2017/07/07 02:59:33
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 08:59:00 (permalink)
0
The OR operation reduced it by 4% to 59%, I am using the free version of the compiler at the moment, I used to get a message when building that the full version could make the code a certain percentage smaller but don't seem to get that message anymore.  
#36
pcbbc
Super Member
  • Total Posts : 1373
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 09:10:11 (permalink)
+1 (1)
btommo
The OR operation reduced it by 4% to 59%, I am using the free version of the compiler at the moment, I used to get a message when building that the full version could make the code a certain percentage smaller but don't seem to get that message anymore. 

It still can.  But if you are just experimenting as a hobbyist, stick with the free version and just get a larger/more capable PIC if you run out of space/performance with the free version.
#37
ric
Super Member
  • Total Posts : 24270
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/15 13:21:21 (permalink)
0
Also note, v2.0x of XC8 permits up to level 2 optimisation in the free version!
 You have to select it on the project properties, it doesn't default to the higher level in a new project.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#38
btommo
Junior Member
  • Total Posts : 117
  • Reward points : 0
  • Joined: 2017/07/07 02:59:33
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/16 06:32:03 (permalink)
0
I tried optimisation level 2 today, it didn't seem to make a difference with the same percentage shown after. I've edit the code to include learning of five different remotes and all seems to be functional, the additional remote uint32_t seems to eat quite a bit of data ram. I had trouble with the learning when I read a connected switch input through the LAT and not the PORT but sorted it out. Silly mistake I know;
 
Writes to PORTA are actually written to corresponding LATA register. Reads from PORTA register is return
of actual I/O pin values.

post edited by btommo - 2019/07/16 06:40:13
#39
pcbbc
Super Member
  • Total Posts : 1373
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: Guidance on 433MHz PIC16F Receiver Project 2019/07/16 07:26:30 (permalink)
0
Well done.
 
btommoI've edit the code to include learning of five different remotes and all seems to be functional, the additional remote uint32_t seems to eat quite a bit of data ram.

Obviously each additional uint32_t should only really use an additional 4 bytes of RAM.  If you store them in an array (as opposed to duplicating the code for each) it shouldn't add that much extra code either.  Post your finished code if you want someone to take a look at it.
#40
Page: < 123 > Showing page 2 of 3
Jump to:
© 2019 APG vNext Commercial Version 4.5