 |
 |
View previous topic :: View next topic |
Author |
Message |
temtronic
Joined: 01 Jul 2010 Posts: 9425 Location: Greensville,Ontario
|
|
Posted: Sat Feb 08, 2025 11:06 am |
|
|
If we knew the make/model of the receiver we could search the web to see how others have done it. Also see where to pick off the correct data.
It would be nice to see at least 2 'data streams after same key pressed'. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Sat Feb 08, 2025 2:04 pm |
|
|
PrinceNai wrote: | You always say: the code doesn't work. Maybe I didn't read all the posts carefully enough, but I don't see exactly WHAT doesn't work. I'm sure the code I posted "works". I know it because what I send from one PIC shows in the buffer of the other PIC. I'm also quite sure the other code from Mr. T works. So, what doesn't work? How do you know it doesn't? If you are relying on your logic analyzer to compare the results, you'll never ever going to see the same thing. Look at the pictures you sent. Where the analyzer "sees" the data? On one of the pictures it ignores at least one byte at the end. If you have an extra PIC, do yourself a favor. Build a transmitter that will send known data every time. Than you can compare sent with received and see if there is a difference and where. Once again, I'm 99,99999% sure the first data bit starts one TE after the 4.800us preamble. I concluded that from the shape of the signals on your pictures. There are 113 bits sent out. Count them from the last one back on the picture that has a logic 1 as the last bit. Also from the shape of the signal. If you start with the first zero after the preamble, you have 0,0,1,1,0,0,1,1. That is NOT Manchester coded data. Your analyzer takes the falling edge of the preamble as the first bit. But to cut it short. What doesn't work? |
@princenai
There is a reason why I say it doesn't work, I have a remote control in my hand and I test it and I see that it doesn't work. You can't know if you have a remote control or not because you don't have the real circuit. If it worked, I wouldn't have to bother with it anyway.
note 56 bit
I understand that the code is not working, after sending data to the remote control, I try Manchester decode and when I read the buffer in the codes I see 0, I understand that the incoming data is not decoded.
Last edited by bulut_01 on Sat Feb 08, 2025 2:11 pm; edited 2 times in total |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Sat Feb 08, 2025 2:06 pm |
|
|
temtronic wrote: | If we knew the make/model of the receiver we could search the web to see how others have done it. Also see where to pick off the correct data.
It would be nice to see at least 2 'data streams after same key pressed'. |
mr. temtronic The receiver circuit is my own design, there is no brand. |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Sat Feb 08, 2025 3:45 pm |
|
|
112 bits of useful data come in. 56 1-0 or 0-1 pairs which translate to 56 bits when decoded.
Quote: |
You can't know if you have a remote control or not because you don't have the real circuit. |
I actually do. Not your remote, of course, but a real, hardware board that mimics the data and the timings from one of the pictures you posted. And a real board on the other side that receives and decodes that data. Connected to a Pickit3 where I can see the contents of the reception buffer. And verify if the state machine reaches the transition points as expected. And a logic analyzer where I can confirm that the data I coded leaves the transmitting board and has the correct pattern.
Quote: |
when I read the buffer in the codes I see 0 |
This is an information. What is actually happening. So, can you confirm that you correctly sense a 4800us impulse that signifies the beginning of the data? If you are not using a debugger, maybe turn on a LED when that is correctly received. You need to eliminate things one by one. Preamble received? Yes, so the problem isn't here. No, wrong timing, interrupts not firing,... |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9425 Location: Greensville,Ontario
|
|
Posted: Sat Feb 08, 2025 3:47 pm |
|
|
OK, what make /model is the transmitter ?
or post 2 complete 'button presses' of the TRANSMITTERS data not from your 'receiver' circuit. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Sat Feb 08, 2025 4:03 pm |
|
|
temtronic wrote: | OK, what make /model is the transmitter ?
or post 2 complete 'button presses' of the TRANSMITTERS data not from your 'receiver' circuit. |
okey same key 2 different data
Last edited by bulut_01 on Mon Feb 24, 2025 1:43 pm; edited 1 time in total |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Sat Feb 08, 2025 5:58 pm |
|
|
This is how the data copied from your picture 55 looks in Excel:
https://ibb.co/gZ5PpGsd
Note the blue row.
My fake transmitter is coded to transmit this sequence of bits. 640us Te, 5 times 4xTe long sync bytes and 7xTe long preamble. Leading zero of Te and 112 bits of data.
This is the result I get in my receiving PIC:
https://ibb.co/99RGr1BD
Look at DecodedInputData |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9425 Location: Greensville,Ontario
|
|
Posted: Sat Feb 08, 2025 9:11 pm |
|
|
Pressing the same key should produce the same data,otherwise the receiver can't control whatever it's supposed to.
Since PN's code works, according to the eXcell-ent analysis, there has to be something odd about the transmitter,
Sadly we don't have any real good information about the device, IE the actual formatting of the data stream. |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Sun Feb 09, 2025 4:52 am |
|
|
Yes, getting the bits over is the easy part. What to do with them once they are there is the question :-).
Here I have no idea if the receiving hardware of the OP even works. I know it is powered on, of course. Is the receiving PIC seeing the data, entering the interrupts? Can it turn on a LED if any kind of transmission is detected? Easy stuff, when a transition is detected, toggle a LED. So when the button is pressed, something blinks on the other side. Maybe a follower, when a signal is detected, set another pin to the same level and hook the analyzer on the input and the output pin. Interrupt on change, when it fires, sample the input and set the output accordingly. 5 lines of code. The pattern should be the same on both channels. How is the debugging done, any kind of output to check what the code is doing? I saw that PickitPlus software is used, but that is a programming software only, not a debugger. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Sun Feb 09, 2025 5:41 am |
|
|
PrinceNai wrote: | Yes, getting the bits over is the easy part. What to do with them once they are there is the question :-).
Here I have no idea if the receiving hardware of the OP even works. I know it is powered on, of course. Is the receiving PIC seeing the data, entering the interrupts? Can it turn on a LED if any kind of transmission is detected? Easy stuff, when a transition is detected, toggle a LED. So when the button is pressed, something blinks on the other side. Maybe a follower, when a signal is detected, set another pin to the same level and hook the analyzer on the input and the output pin. Interrupt on change, when it fires, sample the input and set the output accordingly. 5 lines of code. The pattern should be the same on both channels. How is the debugging done, any kind of output to check what the code is doing? I saw that PickitPlus software is used, but that is a programming software only, not a debugger. |
interrupts rda timer ex_ınt everything is working fully, you must have thought we were amateurs, manch algorithm is not working, I just have circuit design work to finish, I will deal with the published codes |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Sun Feb 09, 2025 6:20 am |
|
|
Quote: | you must have thought we were amateurs |
No, I don't :-). But since you are a bit on the stiff side with the information, I must ask. Must is a bit strong word, at this point I simply want to, because it really interests me. You mentioned all zeroes in the buffer. Fine. Does your code ever reach the point where it must write a one there? Does it increment counters, at least two of them? How can I know that without asking you? I have no idea about the equipment you use, save for the analyzer and the programming software. What are you debugging with? How? You never say: I did this, I tried that. Result is this. I know that my setup works. And it didn't work off the bat, far from it. But I went step by step. There is a diode blinking, so I know my PIC is alive. There was a breakpoint sitting in the first two states so I knew I could catch the preamble every time. Only after that I went to the decoding part. Drew a diagram of one byte and worked out the timings. Catching my own errors, both in code and in mental process. I prove to myself every time that the code does what you write, not what you think it should do. Those two things are seldom the same at the start.
Anyway, I was tinkering with the code since the version posted previously, so this is the last version:
Receiving part:
Code: |
#include <18F46K22.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPUT
#device ICD=TRUE
#use delay(internal = 32000000)
/////////////////////////// DEFINES /////////////////////////////////
#define NUMBER_OF_BYTES 7 // number of DECODED bytes to receive
#define TE 640 // duration of one bit in us, change as needed
#define PREAMBLE_MAX_TIME 8*TE
#define PREAMBLE_MIN_TIME 6*TE // we expect a 7 bit preamble, make some room for clock error
#define TRANSITION_MIN_TIME 1.5*TE // same here when sampling
#define TRANSITION_MAX_TIME 2.5*TE
////////////////////////// VARIABLES ////////////////////////////////
char DecodedInputData[10]; // buffer for decoded data
char CurrentByte = 0;
int8 InputByteCounter = 0; // keeps track about which byte we are filling in
int8 BitPosition = 0; // bit position of the incoming data
int8 Have_Data = 0; // flag to inform main data was received and decoded
// switch
enum {GotRisingEdge = 1, GotFallingEdge, SampleData}; // state machine switch
int8 DecodeSwitch = GotRisingEdge;
// Timer
int16 TimerValue;
int8 TMR0_Overflow = 0; // how many times TMR0 has overflowed
////////////////////////// FUNCTIONS ////////////////////////////////
#bit INTDEG = getenv("BIT:INTCON2.INTEDG0") // declare edge selection bit for INT_EXT. INTDEG is a generic name (some PIC's have more than one of those registers,
void ToggleIntEdge (void){ // 18f46k22 has INTDEG0, for example) for external interrupt on Pin_B0. Change this for the PIC you use
if(INTDEG == 1){ // check which edge is currently selected
INTDEG = 0; // activate interrupt on falling edge
}
else{
INTDEG = 1; // activate interrupt on rising edge
}
}
// ------------------------------------------------------------------
void ClearBuffer (void){
DecodedInputData[0] = 0x00; // lazy :-)
DecodedInputData[1] = 0x00;
DecodedInputData[2] = 0x00;
DecodedInputData[3] = 0x00; // lazy :-)
DecodedInputData[4] = 0x00;
DecodedInputData[5] = 0x00;
DecodedInputData[6] = 0x00;
DecodedInputData[7] = 0x00;
DecodedInputData[8] = 0x00;
DecodedInputData[9] = 0x00;
}
//////////////////////// END OF FUNCTIONS //////////////////////////
// ******************************************************************
// INTERRUPTS
// ******************************************************************
#INT_TIMER0
void TIMER0_isr(void)
{
TMR0_Overflow++; // count timer TMR0_Overflows
}
// ------------------------------------------------------------------
#INT_EXT
void EXT_isr(void)
{
clear_interrupt(INT_EXT); // clear interrupt, needed for this particular interrupt type or you come back straight away
//default handling, check if switch variable is out of usefull bounds
if (DecodeSwitch < 1 || DecodeSwitch > 3)
{
// printf("Default handling, testval is out of bounds, DecodeSwitch == %u\r\n", DecodeSwitch);
continue; // Miss switch. The continue statement causes the next iteration of the enclosing loop(While, For, Do) to begin.
}
// ******************************************************************
// ******************************************************************
switch (DecodeSwitch) // state machine used to receive and decode Mancester encoded data
{
// ------------------------------------------------------------------
// wait for a rising edge on the input, this state also serves as a reset. Always come here with L_TO_H transition set (maybe not even needed)!
case GotRisingEdge: // we have a rising edge, could be start of the preamble
{
set_timer0(0); // reset timer
TMR0_Overflow = 0; // and various counters
BitPosition = 0;
InputByteCounter = 0;
CurrentByte = 0;
Have_Data = 0; // and flags
ext_int_edge(0, H_TO_L); // change direction of the interrupt to falling edge
DecodeSwitch = GotFallingEdge; // and go to GotFallingEdge to see if we have a preamble
break;
}
// ------------------------------------------------------------------
case GotFallingEdge: // we have a falling edge, pulse ended. Might be preamble.
{
ext_int_edge(0, L_TO_H); // prepare next interrupt on a rising edge
TimerValue = get_timer0(); // check the time that elapsed between two interrupts
if(TMR0_Overflow == 0 && TimerValue > PREAMBLE_MIN_TIME && TimerValue < PREAMBLE_MAX_TIME) { // bingo, time is good, we have a preamble
set_timer0(0); // preset timer for next measurement
TMR0_Overflow = 0;
DecodeSwitch = SampleData; // and go sample the input
}
else{ // not good, pulse was either too short or too long for a preamble.
DecodeSwitch = GotRisingEdge; // Reset state machine
}
break;
}
// ------------------------------------------------------------------
// We are looking for a transition that in Mancester coding always exist in the middle of a symbol,
// so the sampling is done every 2TE. That can be on the first or second following interrupt,
// depending on whether two subsequent symbols have the same or different value.
// We are using TMR0 value to find if it is time to sample. If it is, sample the input and store
// to the correct location in the data buffer.
// The word symbol means a 2-bit pair that represents either a 1 or a 0.
case SampleData:
{
ToggleIntEdge(); // change the active edge of the interrupt for the next one,
// because transition can be either 0-1 or 1-0, but hardly
// 0-0 or 1-1
TimerValue = get_timer0();
// If this interrupt occured in a time frame from 0,5*TE to 1,5*TE, this symbol has the same
// value as the previous, meanng that interrupt occured also at the start of the symbol, not only in the middle.
// So we need to wait for the next interrupt that will come at the middle of a symbol to actually sample data
// Time between two edges is correct, read input state. This test is intentionally put in the first place
// so it gets serviced first, since the timer is already running for the next symbol
if(TMR0_Overflow == 0 && TimerValue >= TRANSITION_MIN_TIME && TimerValue <= TRANSITION_MAX_TIME){ // this is the one we are looking for, sample and store the data
set_timer0(0); // reset timer for the next symbol
// INVERT THE DECODING LOGIC AS NEEDED HERE!!!!! COMMENT THE WRONG IF OUT!!!! LIKE THIS WORKS FOR IEEE 802 CODING, 01 IS 1, 10 IS 0
// if(input_state(pin_B0) == 0){
if(input_state(pin_B0) == 1){
bit_set(CurrentByte, 7 - BitPosition); // Sample input. Set appropriate bit if needed, leave 0 otherwise
} //
BitPosition++;
if(BitPosition > 7){ // one byte of data was received
BitPosition = 0;
DecodedInputData[InputByteCounter] = CurrentByte; // store that data into the buffer
CurrentByte = 0; // prepare variable for next byte (all zeroes, since we are only setting the bits needed)
InputByteCounter++; // increment byte counter for a correct position in the buffer
if (InputByteCounter == NUMBER_OF_BYTES){ // if all the bytes are in the buffer, reception is done
ext_int_edge(0, L_TO_H);
Have_Data = 1; // we have data, signal that to main
DecodeSwitch = GotRisingEdge; // and reset state machine for the next reception
} // if byte counter
} // if bit position
} // end sampling
// time between two edges is too short for sampling, it may be transition between two symbols with the same value
else if(TMR0_Overflow == 0 && TimerValue < TRANSITION_MIN_TIME){ // the transition came too soon for sampling, exit interrupt but leave
delay_cycles(1); // the timer running and stay in the same case
}
// time between two edges to long for a valid symbol, reset
else{ // time between two transitions was too long,
ext_int_edge(0, L_TO_H);
DecodeSwitch = GotRisingEdge; // reset state machine
}
break;
} // end case
} // end switch
} // end interrupt
// ******************************************************************
// END OF INTERRUPTS
// ******************************************************************
void main()
{
ClearBuffer(); // clear receiving buffer
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8); // 65.535us, resolution 1us. RESOLUTION MUST BE 1us!!!!
clear_interrupt(INT_EXT);
ext_int_edge(0,L_TO_H);
enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(Have_Data == 1){
Have_Data = 0; // do something with data
}
}
}
|
and the code used to send the data out, full 14 bytes, copied from the picture:
Code: |
#include <18F46K22.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPUT
//#device ICD=TRUE
#use delay(internal=32000000)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,force_hw)
// ******************************************************************
int8 k;
// buttons
#define MODE_switch PIN_B1
int8 active_state_MODE;
int8 previuos_state_MODE;
int8 MODE_switch_is_pressed = FALSE;
#define Te 640
#define Transmit_Pin PIN_B5
////////////////////////// FUNCTIONS ////////////////////////////////
// ------------------------------------------------------------------
void i (void){
// 1
output_high(Transmit_Pin);
delay_us(Te);
output_low(Transmit_Pin);
delay_us(Te);
}
// ------------------------------------------------------------------
void o (void){
// 0
output_low(Transmit_Pin);
delay_us(Te);
output_high(Transmit_Pin);
delay_us(Te);
}
// ------------------------------------------------------------------
void ReadModeButton(void){
// detect ModeButton, presumes 0 is read if the ModeButton is pressed.Debouncing part.
active_state_MODE = input_state(MODE_switch); // Read the button
if((previuos_state_MODE == 1) && (active_state_MODE == 0)){
MODE_switch_is_pressed = TRUE; // switch pressed, raise "MODE PRESSED" flag
} // must be cleared in software
previuos_state_MODE = active_state_MODE; // Save current value for next time
}
// ------------------------------------------------------------------
// bit 6 controls the active edge for INT_EXT
#bit INTDEG = getenv("BIT:INTCON2.INTEDG0") // declare edge selection bit for INT_EXT. INTDEG is a generic name (some PIC's have more than one of those registers,
void ToggleIntEdge (void){ // 18f46k22 has INTDEG0, for example) for external interrupt on Pin_B0. Change this for the PIC you use
if(INTDEG == 1){
INTDEG = 0; // check which edge is currently selected
}
else{
INTDEG = 1; // and change to the oposite edge
}
}
// ******************************************************************
#INT_TIMER0
void TIMER0_isr(void)
{
ReadModeButton();
}
// ------------------------------------------------------------------
void main()
{
output_low(Transmit_Pin);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // 125ns cycle, 8 ms overflow
enable_interrupts(INT_TIMER0); // timer0 takes care of buttons and timings
enable_interrupts(GLOBAL);
while(TRUE)
{
//////
if(MODE_switch_is_pressed == TRUE){
MODE_switch_is_pressed = FALSE;
disable_interrupts(INT_TIMER0); // prevent button presses while sending
ToggleIntEdge();
// wait -------------------------------------------------------------
output_low(Transmit_Pin);
delay_ms(2000);
// sync -------------------------------------------------------------
for(k= 0; k < 5; k++){
output_high(Transmit_Pin);
delay_us(4*Te);
output_low(Transmit_Pin);
delay_us(4*Te);
}
// preamble ---------------------------------------------------------
output_high(Transmit_Pin);
delay_us(7*Te);
output_low(Transmit_Pin);
// leading 0
delay_us(Te);
// data -------------------------------------------------------------
// byte1 ----------
// 0
o();
// 1
i();
// 0
o();
// 1
i();
// byte2 ----------
// 1
i();
// 0
o();
// 1
i();
// 0
o();
// byte3 ---------
// 0
o();
// 1
i();
// 1
i();
// 1
i();
// byte4 ---------
// 0
o();
// 0
o();
// 0
o();
// 0
o();
// byte5 ----------
// 0
o();
// 0
o();
// 0
o();
// 0
o();
// byte6 ----------
// 1
i();
// 1
i();
// 1
i();
// 0
o();
// byte7 ----------
// 1
i();
// 1
i();
// 1
i();
// 1
i();
// byte8 ----------
// 1
i();
// 0
o();
// 1
i();
// 0
o();
// byte9 ----------
// 0
o();
// 1
i();
// 1
i();
// 0
o();
// byte10 ----------
// 1
i();
// 0
o();
// 0
o();
// 1
i();
// byte11 ----------
// 1
i();
// 0
o();
// 0
o();
// 1
i();
// byte12 ----------
// 1
i();
// 0
o();
// 0
o();
// 1
i();
// byte13 ----------
// 1
i();
// 0
o();
// 1
i();
// 0
o();
// byte14 ----------
// 1
i();
// 0
o();
// 1
i();
// 0
o();
// pause ------------------------------------------------------------
output_low(Transmit_Pin);
delay_ms(500);
enable_interrupts(INT_TIMER0);
}
//////////////////
}
}
|
|
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9425 Location: Greensville,Ontario
|
|
Posted: Sun Feb 09, 2025 10:49 am |
|
|
hmm, just thinking, it'd be kind of funny if the received data bits are actually inverted from the transmitted ones.....  |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Sun Feb 09, 2025 11:19 am |
|
|
What exactly do you mean by "inverted"? Inverted Manchester logic (that is taken care of in the code, comment/un-comment one line) or sent out LSB first? Last two pictures sure do look very similar at the end. It shouldn't be too hard to rearrange 56 bits so that the last one comes on the first place and so on. And of course type in the pattern also for the other picture, I only did one. |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9425 Location: Greensville,Ontario
|
|
Posted: Sun Feb 09, 2025 11:33 am |
|
|
I saw that there's 2 versions of Manchester...yeesh, so much for 'standards'......
Haven't seen a proper breakdown of the data ,least not that I can recall so wondering why 2 keypresses aren't the same.
I still have 20cm of snow to deal with, ugh......so my breaktime is over. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Sun Feb 09, 2025 12:01 pm |
|
|
PrinceNai wrote: | Quote: | you must have thought we were amateurs |
No, I don't :-). But since you are a bit on the stiff side with the information, I must ask. Must is a bit strong word, at this point I simply want to, because it really interests me. You mentioned all zeroes in the buffer. Fine. Does your code ever reach the point where it must write a one there? Does it increment counters, at least two of them? How can I know that without asking you? I have no idea about the equipment you use, save for the analyzer and the programming software. What are you debugging with? How? You never say: I did this, I tried that. Result is this. I know that my setup works. And it didn't work off the bat, far from it. But I went step by step. There is a diode blinking, so I know my PIC is alive. There was a breakpoint sitting in the first two states so I knew I could catch the preamble every time. Only after that I went to the decoding part. Drew a diagram of one byte and worked out the timings. Catching my own errors, both in code and in mental process. I prove to myself every time that the code does what you write, not what you think it should do. Those two things are seldom the same at the start.
Anyway, I was tinkering with the code since the version posted previously, so this is the last version:
Receiving part:
Code: |
#include <18F46K22.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPUT
#device ICD=TRUE
#use delay(internal = 32000000)
/////////////////////////// DEFINES /////////////////////////////////
#define NUMBER_OF_BYTES 7 // number of DECODED bytes to receive
#define TE 640 // duration of one bit in us, change as needed
#define PREAMBLE_MAX_TIME 8*TE
#define PREAMBLE_MIN_TIME 6*TE // we expect a 7 bit preamble, make some room for clock error
#define TRANSITION_MIN_TIME 1.5*TE // same here when sampling
#define TRANSITION_MAX_TIME 2.5*TE
////////////////////////// VARIABLES ////////////////////////////////
char DecodedInputData[10]; // buffer for decoded data
char CurrentByte = 0;
int8 InputByteCounter = 0; // keeps track about which byte we are filling in
int8 BitPosition = 0; // bit position of the incoming data
int8 Have_Data = 0; // flag to inform main data was received and decoded
// switch
enum {GotRisingEdge = 1, GotFallingEdge, SampleData}; // state machine switch
int8 DecodeSwitch = GotRisingEdge;
// Timer
int16 TimerValue;
int8 TMR0_Overflow = 0; // how many times TMR0 has overflowed
////////////////////////// FUNCTIONS ////////////////////////////////
#bit INTDEG = getenv("BIT:INTCON2.INTEDG0") // declare edge selection bit for INT_EXT. INTDEG is a generic name (some PIC's have more than one of those registers,
void ToggleIntEdge (void){ // 18f46k22 has INTDEG0, for example) for external interrupt on Pin_B0. Change this for the PIC you use
if(INTDEG == 1){ // check which edge is currently selected
INTDEG = 0; // activate interrupt on falling edge
}
else{
INTDEG = 1; // activate interrupt on rising edge
}
}
// ------------------------------------------------------------------
void ClearBuffer (void){
DecodedInputData[0] = 0x00; // lazy :-)
DecodedInputData[1] = 0x00;
DecodedInputData[2] = 0x00;
DecodedInputData[3] = 0x00; // lazy :-)
DecodedInputData[4] = 0x00;
DecodedInputData[5] = 0x00;
DecodedInputData[6] = 0x00;
DecodedInputData[7] = 0x00;
DecodedInputData[8] = 0x00;
DecodedInputData[9] = 0x00;
}
//////////////////////// END OF FUNCTIONS //////////////////////////
// ******************************************************************
// INTERRUPTS
// ******************************************************************
#INT_TIMER0
void TIMER0_isr(void)
{
TMR0_Overflow++; // count timer TMR0_Overflows
}
// ------------------------------------------------------------------
#INT_EXT
void EXT_isr(void)
{
clear_interrupt(INT_EXT); // clear interrupt, needed for this particular interrupt type or you come back straight away
//default handling, check if switch variable is out of usefull bounds
if (DecodeSwitch < 1 || DecodeSwitch > 3)
{
// printf("Default handling, testval is out of bounds, DecodeSwitch == %u\r\n", DecodeSwitch);
continue; // Miss switch. The continue statement causes the next iteration of the enclosing loop(While, For, Do) to begin.
}
// ******************************************************************
// ******************************************************************
switch (DecodeSwitch) // state machine used to receive and decode Mancester encoded data
{
// ------------------------------------------------------------------
// wait for a rising edge on the input, this state also serves as a reset. Always come here with L_TO_H transition set (maybe not even needed)!
case GotRisingEdge: // we have a rising edge, could be start of the preamble
{
set_timer0(0); // reset timer
TMR0_Overflow = 0; // and various counters
BitPosition = 0;
InputByteCounter = 0;
CurrentByte = 0;
Have_Data = 0; // and flags
ext_int_edge(0, H_TO_L); // change direction of the interrupt to falling edge
DecodeSwitch = GotFallingEdge; // and go to GotFallingEdge to see if we have a preamble
break;
}
// ------------------------------------------------------------------
case GotFallingEdge: // we have a falling edge, pulse ended. Might be preamble.
{
ext_int_edge(0, L_TO_H); // prepare next interrupt on a rising edge
TimerValue = get_timer0(); // check the time that elapsed between two interrupts
if(TMR0_Overflow == 0 && TimerValue > PREAMBLE_MIN_TIME && TimerValue < PREAMBLE_MAX_TIME) { // bingo, time is good, we have a preamble
set_timer0(0); // preset timer for next measurement
TMR0_Overflow = 0;
DecodeSwitch = SampleData; // and go sample the input
}
else{ // not good, pulse was either too short or too long for a preamble.
DecodeSwitch = GotRisingEdge; // Reset state machine
}
break;
}
// ------------------------------------------------------------------
// We are looking for a transition that in Mancester coding always exist in the middle of a symbol,
// so the sampling is done every 2TE. That can be on the first or second following interrupt,
// depending on whether two subsequent symbols have the same or different value.
// We are using TMR0 value to find if it is time to sample. If it is, sample the input and store
// to the correct location in the data buffer.
// The word symbol means a 2-bit pair that represents either a 1 or a 0.
case SampleData:
{
ToggleIntEdge(); // change the active edge of the interrupt for the next one,
// because transition can be either 0-1 or 1-0, but hardly
// 0-0 or 1-1
TimerValue = get_timer0();
// If this interrupt occured in a time frame from 0,5*TE to 1,5*TE, this symbol has the same
// value as the previous, meanng that interrupt occured also at the start of the symbol, not only in the middle.
// So we need to wait for the next interrupt that will come at the middle of a symbol to actually sample data
// Time between two edges is correct, read input state. This test is intentionally put in the first place
// so it gets serviced first, since the timer is already running for the next symbol
if(TMR0_Overflow == 0 && TimerValue >= TRANSITION_MIN_TIME && TimerValue <= TRANSITION_MAX_TIME){ // this is the one we are looking for, sample and store the data
set_timer0(0); // reset timer for the next symbol
// INVERT THE DECODING LOGIC AS NEEDED HERE!!!!! COMMENT THE WRONG IF OUT!!!! LIKE THIS WORKS FOR IEEE 802 CODING, 01 IS 1, 10 IS 0
// if(input_state(pin_B0) == 0){
if(input_state(pin_B0) == 1){
bit_set(CurrentByte, 7 - BitPosition); // Sample input. Set appropriate bit if needed, leave 0 otherwise
} //
BitPosition++;
if(BitPosition > 7){ // one byte of data was received
BitPosition = 0;
DecodedInputData[InputByteCounter] = CurrentByte; // store that data into the buffer
CurrentByte = 0; // prepare variable for next byte (all zeroes, since we are only setting the bits needed)
InputByteCounter++; // increment byte counter for a correct position in the buffer
if (InputByteCounter == NUMBER_OF_BYTES){ // if all the bytes are in the buffer, reception is done
ext_int_edge(0, L_TO_H);
Have_Data = 1; // we have data, signal that to main
DecodeSwitch = GotRisingEdge; // and reset state machine for the next reception
} // if byte counter
} // if bit position
} // end sampling
// time between two edges is too short for sampling, it may be transition between two symbols with the same value
else if(TMR0_Overflow == 0 && TimerValue < TRANSITION_MIN_TIME){ // the transition came too soon for sampling, exit interrupt but leave
delay_cycles(1); // the timer running and stay in the same case
}
// time between two edges to long for a valid symbol, reset
else{ // time between two transitions was too long,
ext_int_edge(0, L_TO_H);
DecodeSwitch = GotRisingEdge; // reset state machine
}
break;
} // end case
} // end switch
} // end interrupt
// ******************************************************************
// END OF INTERRUPTS
// ******************************************************************
void main()
{
ClearBuffer(); // clear receiving buffer
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8); // 65.535us, resolution 1us. RESOLUTION MUST BE 1us!!!!
clear_interrupt(INT_EXT);
ext_int_edge(0,L_TO_H);
enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(Have_Data == 1){
Have_Data = 0; // do something with data
}
}
}
|
|
16F1824 register not
Code: | #bit INTDEG = getenv("BIT:INTCON2.INTEDG0") |
|
|
 |
|
|
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
|