 |
 |
View previous topic :: View next topic |
Author |
Message |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Wed Feb 12, 2025 9:25 am |
|
|
PrinceNai wrote: | Then use Timer1. Change all references from Timer0 to Timer1. Mind you, overflow isn't 1us. Timer increments by 1 in 1us. Overflow is 65ms |
ayarları bu şekilde yapınca kod baya ilerledi yanlız sonuca varamadım.
resimdeki mor bölüm ''InputByteCounter'' sayac paket bitiminde 7 olması gerekirken 2 kalıyor ve doğal olarak paket bittiği için sıfırlanıyor.
Last edited by bulut_01 on Mon Feb 24, 2025 1:44 pm; edited 1 time in total |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Wed Feb 12, 2025 10:27 am |
|
|
I didn't go further:
Code: |
#define TRANSITION_MIN_TIME 8 * TE // same here when sampling
#define TRANSITION_MAX_TIME 12 * TE |
|
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9425 Location: Greensville,Ontario
|
|
Posted: Wed Feb 12, 2025 10:32 am |
|
|
translation from Google....
When I made the settings like this, the code progressed a lot but I couldn't reach the result. The purple part in the picture is the ''InputByteCounter'' counter, which should be 7 at the end of the packet, remains 2 and naturally resets to zero when the packet ends. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Wed Feb 12, 2025 10:34 am |
|
|
PrinceNai wrote: | I didn't go further:
Code: |
#define TRANSITION_MIN_TIME 8 * TE // same here when sampling
#define TRANSITION_MAX_TIME 12 * TE |
|
In your settings, the code is stuck at the beginning. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Wed Feb 12, 2025 10:35 am |
|
|
temtronic wrote: | translation from Google....
When I made the settings like this, the code progressed a lot but I couldn't reach the result. The purple part in the picture is the ''InputByteCounter'' counter, which should be 7 at the end of the packet, remains 2 and naturally resets to zero when the packet ends. |
true |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Wed Feb 12, 2025 11:30 am |
|
|
Quote: | In your settings, the code is stuck at the beginning. |
Where exactly?
I just tried again. With the test program and the timings I have there it doesn't. 20x, 20x the same data appears on the receiving end.
With this
Code: | PREAMBLE_MIN_TIME 4 * TE | the program might be mistaking sync pulses for a preamble. I suppose in that case nothing will work. I remember vaguely that it was written somewhere that sync pulses are 4*Te long?
Edit: I lowered that time and I was right. It doesn't work at all. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Wed Feb 12, 2025 3:57 pm |
|
|
PrinceNai wrote: | Quote: | In your settings, the code is stuck at the beginning. |
Where exactly?
I just tried again. With the test program and the timings I have there it doesn't. 20x, 20x the same data appears on the receiving end.
With this
Code: | PREAMBLE_MIN_TIME 4 * TE | the program might be mistaking sync pulses for a preamble. I suppose in that case nothing will work. I remember vaguely that it was written somewhere that sync pulses are 4*Te long?
Edit: I lowered that time and I was right. It doesn't work at all. |
Last edited by bulut_01 on Mon Feb 24, 2025 1:45 pm; edited 2 times in total |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9425 Location: Greensville,Ontario
|
|
Posted: Wed Feb 12, 2025 5:11 pm |
|
|
this....
TMR0_Overflow ++;
is really bad programming as it should be labeled
TMR1_Overflow++ ;
While it mat not be 'the' problem, it's very distracting and confusing !
Also delete any commented out code that serves no purpose, again it's visual clutter, making it more difficult to see he actual program flow. |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Wed Feb 12, 2025 6:49 pm |
|
|
The only number that is meant to be changed inside the defines is TE. That is the width of the data bit or 640us in your case. All the other are based on that one.
PREAMBLE_MAX_TIME 8 * TE
PREAMBLE_MIN_TIME 6 * TE
A preamble of approx 4500us is expected. To allow for some timer errors from both side it is safe to assume it will be between 3800us and 5200us. That is what those two defines mean.
TRANSITION_MIN_TIME 1.5 * TE
TRANSITION_MAX_TIME 2.5 * TE
Min and max here must be smaller, of course. They are catching if the transition between two symbols is within limits. That cannot be 13xTE, especially not with Manchester coding were the largest number of two consecutive bits with the same value is limited to exactly 2. Your numbers in these defines make no sense.
I'll tell you again. The code works. Works live, even works in Proteus. With 18f46k22 and 16f1824. I just tested it. I have no idea what you are doing. Mixing Proteus, live gadget, changing numbers in code, not sharing what happened. Yes, I do know SOMETHING doesn't work for you. But you are not telling what and where it fails. Just that it doesn't work. That is a kind of problem description I expect from my wife. TV doesn't work. How can I know what doesn't work? Describe the problem. Below is the code with your chip, tested in Proteus. It happily receives six bytes of data and decodes them.
Code: |
#include <16F1824.h> //RF TEST CODE
#device ADC = 8 //VERSION_5
//#device ICD = TRUE
#FUSES NOWDT
#fuses noPUT
//
#FUSES NOMCLR
#FUSES NOLVP
#FUSES NOSTVREN
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES NOWRT
#FUSES NODEBUG
#use delay(internal = 32M)
//
#OPT 9
//
//#use fast_io(A)
//#use fast_io(C)
//
#use rs232(baud = 1600, parity = N, xmit = PIN_a0, rcv = PIN_a1, bits = 8, STREAM = UART1, stop = 1, errors) //uart setup
/////////////////////////////////////////////////////////////////////////////// register set.
#byte PIR3 = 0x013
#bit CCP3IF = PIR3.4
#byte CCP3CON = 0X313
#bit CCP3M3 = CCP3CON.3
//#byte TMR0 = 0x015
#byte INTCON = 0X00B
#bit T0IF = INTCON.2
#bit T0IE = INTCON.5
///////////////////////////////////////////////////////////////////////////////
#define led pin_c3
/////////////////////////////////////////////////////////////////////////////// global variable
int8 ready = 0;
///////////////////////////////////////////////////////////////////////////////
/////////////////////////// DEFINES ///////////////////////////////////////////
#define NUMBER_OF_BYTES 3 // number of DECODED bytes to receive
#define TE 640 // duration of one bit in us, change as needed
#define PREAMBLE_MAX_TIME 8 * TE //8
#define PREAMBLE_MIN_TIME 6 * TE //6 // we expect a 7 bit preamble, make some room for clock error
#define TRANSITION_MIN_TIME 1.5 * TE //1.5 // same here when sampling
#define TRANSITION_MAX_TIME 2.5 * TE //2.5
////////////////////////// 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
enum {GotRisingEdge = 1, GotFallingEdge, SampleData}; // state machine switch
int8 DecodeSwitch = GotRisingEdge;
int16 TimerValue;
int8 TMR1_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,
#bit INTEDG = getenv("BIT:OPTION_REG.INTEDG")
void ToggleIntEdge(void){ // 18f46k22 has INTDEG0, for example) for external interrupt on Pin_B0. Change this for the PIC you use
if(INTEDG == 1){ // check which edge is currently selected
INTEDG = 0; // activate interrupt on falling edge
}
else{
INTEDG = 1; // activate interrupt on rising edge
}
}
// ----------------------------------------------------------------------------
void ClearBuffer (void){
DecodedInputData[0] = 0x00;
DecodedInputData[1] = 0x00;
DecodedInputData[2] = 0x00;
DecodedInputData[3] = 0x00;
DecodedInputData[4] = 0x00;
DecodedInputData[5] = 0x00;
DecodedInputData[6] = 0x00;
}
//////////////////////// END OF FUNCTIONS ////////////////////////////////////
// ****************************************************************************
// INTERRUPTS
// ****************************************************************************
#INT_TIMER1
void TIMER1_isr(void)
{
TMR1_Overflow ++; // count timer TMR1_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
// ******************************************************************
// ******************************************************************
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_timer1(0); // reset timer
TMR1_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_timer1(); // check the time that elapsed between two interrupts
if(TMR1_Overflow == 0 && TimerValue > PREAMBLE_MIN_TIME && TimerValue < PREAMBLE_MAX_TIME){ // bingo, time is good, we have a preamble
//putc(get_timer1());
set_timer1(0); // preset timer for next measurement
TMR1_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;
}
// ------------------------------------------------------------------
case SampleData:
{
ToggleIntEdge();
TimerValue = get_timer1();
if(TMR1_Overflow == 0 && TimerValue >= TRANSITION_MIN_TIME && TimerValue <= TRANSITION_MAX_TIME){ // this is the one we are looking for, sample and store the data
//putc(get_timer1());
set_timer1(0); // reset timer for the next symbol
//if(input_state(pin_A2) == 0){
if(input_state(pin_A2) == 1){
bit_set(CurrentByte, 7 - BitPosition); // Sample input. Set appropriate bit if needed, leave 0 otherwise
}
BitPosition ++;
//PUTC(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
//putc(InputByteCounter);
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(TMR1_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
///////////////////////////////////////////////////////////////////////////////
void ready_()
{
for(int i = 0; i < 7; i++){
putc(DecodedInputData[i]);
}
ready = 0;
}
///////////////////////////////////////////////////////////////////////////////
void main()
{
setup_comparator(NC_NC_NC_NC);
ClearBuffer(); // clear receiving buffer
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); //65.5 ms overflow
enable_interrupts(INT_TIMER1);
set_timer1(0);
//
clear_interrupt(INT_EXT);
ext_int_edge(0 , L_TO_H);
enable_interrupts(INT_EXT);
//
disable_interrupts(int_rda);
disable_interrupts(INT_TBE);
enable_interrupts(GLOBAL);
//
//
while(true){
///////////////////////////////////////////////////////////////////////////////
if(Have_Data == 1){
ready = 1;
Have_Data = 0;
}
//
if(ready == 1){
ready_();
}
}
}
|
I used digital pattern generator connected to A3, settings Pattern, equal mark (640us), continuous sequence, specific pulse train, first edge at 3s. The pattern is:
LLLLLLLLLLHHHHLLLLHHHHLLLLHHHHLLLLHHHHHHHLLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLLLLLLLLLL |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Thu Feb 13, 2025 4:11 am |
|
|
I finally managed to run the code.Thank you for all your support.
thank you mr.temtronic
thank you mr.princenai
thank you mr.ttelmah
Last edited by bulut_01 on Mon Feb 24, 2025 1:46 pm; edited 1 time in total |
|
 |
PrinceNai
Joined: 31 Oct 2016 Posts: 527 Location: Montenegro
|
|
Posted: Thu Feb 13, 2025 6:30 am |
|
|
The way I see it, you have finally won :-). That was the whole idea, to get 14 bytes of coded data and get 7 bytes of decoded data. From the picture I'd say that's exactly it.
Great :-) |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9425 Location: Greensville,Ontario
|
|
Posted: Thu Feb 13, 2025 6:37 am |
|
|
gee, here I was thinking we'd get to page 20 before 'tada' !!!
Nice to see it WORKS.....
I do suggest changing the fuse noPUT to PUT. Power Up Timer allows for the PIC to properly 'organize' itself. While not a 'requirement', it costs nothing in real time.
Also COPY your program and SAVE it under a new name, before making any changes !!! |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Thu Feb 13, 2025 6:42 am |
|
|
Without you, my job would have been very difficult. This code that has been tearing my hair out for weeks has finally been finalized. Mr.Temtronic, I will do your suggestions. |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Thu Feb 13, 2025 6:43 am |
|
|
temtronic wrote: | gee, here I was thinking we'd get to page 20 before 'tada' !!!
Nice to see it WORKS.....
I do suggest changing the fuse noPUT to PUT. Power Up Timer allows for the PIC to properly 'organize' itself. While not a 'requirement', it costs nothing in real time.
Also COPY your program and SAVE it under a new name, before making any changes !!! |
I'm sorry it didn't reach 20 pages.  |
|
 |
bulut_01
Joined: 24 Feb 2024 Posts: 206
|
|
Posted: Thu Feb 13, 2025 6:45 am |
|
|
This topic has a very high rating  |
|
 |
|
|
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
|