packet streaming

General discussion on mikroC.
Author
Message
atommic22
Posts: 24
Joined: 17 May 2008 12:39

#31 Post by atommic22 » 23 May 2008 03:20

UREAKA! (forgive the spelling lol). The encoder and decoder work perfectly. The buttons are contorlling the lights corretly. The only discrepancy is that on startup, the LEDs send out incorrect signals for a few seconds untill the decoder syncronises with the input.

Encoder:

Code: Select all

void main() {
CMCON = 7;             // turns of the analog comparators on the PORTA pins
                       // ensures pins are reading digital
TRISA = 0xFF;          // set PORTA to be input

// Initialize USART module
Usart_Init(4800);

  do {
     Usart_write(PORTA);
  } while (1);
}//~!
Decoder:

Code: Select all

void main() {
  CMCON = 7;          // Comparators off
  TRISA = 0;          // set PORTA to be output
  PORTA = 0xFF;       // initialize PORTB


  // Initialize USART module (8 bit, 2400 baud rate, no parity bit..)
  Usart_Init(4800);

  do {
    if (Usart_Data_Ready()) {   // If data is received
      PORTA = Usart_Read();         // Read the received data
    }
  } while (1);
}//~!
Now all that's left to do is wire it to work through my Rx/Tx pair and i should have a good remote control.

Thanx everyone for all your help. I wouldnt have been able to get this working without you. I just have one quiery though. Is there any way to get an 8 bit output with these PICs? Or would I have to go to the 18F series that use more pins?[/code]

drdoug
Posts: 1074
Joined: 16 Aug 2007 03:49
Location: St. Louis, MO

#32 Post by drdoug » 23 May 2008 04:19

atommic22 wrote:Is there any way to get an 8 bit output with these PICs? Or would I have to go to the 18F series that use more pins?
The 16f687/689 have an 8 bit wide port (PORT C) if that is what you mean. It is a 20 pin chip. I am using it for a serial port box project now.
( I am now going to repeat what I said in an earlier post)
I have done a similar project to the one you are doing. Instead of just sending the PORTA values, consider sending the following:

Code: Select all

     USART_Write(49);       // 1   - preamble/sync byte
     USART_Write(49);       // 1  - preamble/sync byte
     USART_Write(49);       // 1  - preamble/sync byte
     USART_Write(65);       // A  - Look for this byte as the start of your data
     USART_Write(PORTA);   // Your Data
     USART_Write(66);       // B - Look for this byte as the end of your data
     USART_Write(35);       // # - push one more byte through
     Delay_ms(45);          // my project worked better with this delay here?
Save the data in an array (ie. char rxdata[2]) and if rxdata[0] = "A" and rxdata[1] = "B" then you can be pretty sure that rxdata[1] is what you want.

You are very, very likely to get a lot of noise on your receiver and get a lot of garabage data coming into your USART rx pin and you have to find your data in that mess. The above example helps you find it.

The receive end might look something like this:

Code: Select all

   while (1) {
     if (USART_Data_Ready()) {            // if data is received
       i = USART_Read();                  // read the received data
       if (i == 65) {                  // is it and "A" ?
         rxchar = 0;
         while (rxchar < 3)  {
            if (USART_Data_Ready()) {
             rxdata[rxchar] = USART_Read();
             rxchar ++;
             }
          } // end while(rxchar)
      if ((rxdata[0] == 65) && (rxdata[2] == 66)) {
         PORTA = rxdata[1];
         rxdata[0] = rxdata[1] =rxdata[2]  = rxchar = 0;
          }
     } // end while

 
It is not the exact code I used but I tried to strip it down so it is legible. There may be parts that don't work but it should give you guidance.
It will work better in an interrupt routine but you may not be ready for that yet. Also a reset timer would be good to kick me out of the routine if I geet an "A" as noise and no other "noise" comes in before the real signal but then that is another reason to have the preamble of "1"s at the beginning.

rinxai
Posts: 7
Joined: 04 Dec 2007 22:12

#33 Post by rinxai » 25 May 2008 22:04

Interesting stuff!

@ atommic - glad you got it working.

Can anyone suggest some TX/RX chips IR or RF to experiment with.

Thanks

blips
Posts: 30
Joined: 11 Nov 2007 22:28

#34 Post by blips » 26 May 2008 10:33

I have been using RXM-433-LC for RX and TXM-433-LC for TX with excellent results. They are both modules from LINX and can be set up without any external components, only thing that you need is an antenna. which in my case is a 6.5" wire.

These two that I mentioned are in 433 MHz freq, however they are available in 2 or 3 other frequencies if I recall correctly.

Cheers,
Blips

rinxai
Posts: 7
Joined: 04 Dec 2007 22:12

#35 Post by rinxai » 26 May 2008 13:58

blips wrote:I have been using RXM-433-LC for RX and TXM-433-LC for TX with excellent results. They are both modules from LINX and can be set up without any external components
appreciated :)

atommic22
Posts: 24
Joined: 17 May 2008 12:39

#36 Post by atommic22 » 01 Jun 2008 13:47

Well the USART PICs work fine for translating parallel data in series. However there's a slight problem with spurious outputs when the decoder PIC scans for the USART sequence. The motors can make erratic motions in the first few seconds before stabilizing.
Other than this there are no major difficulties. We hit a snag though when hooking up the wirless transmitter module to its power supply, we accidentally shorted it to 7V when it's a 3.3V device. We have to re-order another. But for a bright 25 minutes the project was working spledidly, haha.

Image

here you can see that we ran a hard line strait to the decoder chip to further test our project.

Image

our Reciever Shcematic is yet to be printed. Hopefully we can get it operational by the time the new transmitter comes in a week.

Thanx everybody so far and please forward any more advice you would think would be nessisary.

Regards,
Atommic.

atommic22
Posts: 24
Joined: 17 May 2008 12:39

#37 Post by atommic22 » 10 Jul 2008 12:16

Hey thought I'd post an update on the project, We have the particulars figured out and i've tinkered with the code more. I'm happy to say that our surviellence rover is well on the way to completion. I ecpet the unit to be completley functional in the following few weeks.

This is the encoder/transmitter PCB
Image


This is the decoder/reciever PCB
Image

atommic22
Posts: 24
Joined: 17 May 2008 12:39

#38 Post by atommic22 » 18 Jul 2008 03:21

drdoug wrote:
atommic22 wrote:Is there any way to get an 8 bit output with these PICs? Or would I have to go to the 18F series that use more pins?
The 16f687/689 have an 8 bit wide port (PORT C) if that is what you mean. It is a 20 pin chip. I am using it for a serial port box project now.
( I am now going to repeat what I said in an earlier post)
I have done a similar project to the one you are doing. Instead of just sending the PORTA values, consider sending the following:

Code: Select all

     USART_Write(49);       // 1   - preamble/sync byte
     USART_Write(49);       // 1  - preamble/sync byte
     USART_Write(49);       // 1  - preamble/sync byte
     USART_Write(65);       // A  - Look for this byte as the start of your data
     USART_Write(PORTA);   // Your Data
     USART_Write(66);       // B - Look for this byte as the end of your data
     USART_Write(35);       // # - push one more byte through
     Delay_ms(45);          // my project worked better with this delay here?
Save the data in an array (ie. char rxdata[2]) and if rxdata[0] = "A" and rxdata[1] = "B" then you can be pretty sure that rxdata[1] is what you want.

You are very, very likely to get a lot of noise on your receiver and get a lot of garabage data coming into your USART rx pin and you have to find your data in that mess. The above example helps you find it.

The receive end might look something like this:

Code: Select all

   while (1) {
     if (USART_Data_Ready()) {            // if data is received
       i = USART_Read();                  // read the received data
       if (i == 65) {                  // is it and "A" ?
         rxchar = 0;
         while (rxchar < 3)  {
            if (USART_Data_Ready()) {
             rxdata[rxchar] = USART_Read();
             rxchar ++;
             }
          } // end while(rxchar)
      if ((rxdata[0] == 65) && (rxdata[2] == 66)) {
         PORTA = rxdata[1];
         rxdata[0] = rxdata[1] =rxdata[2]  = rxchar = 0;
          }
     } // end while

 
It is not the exact code I used but I tried to strip it down so it is legible. There may be parts that don't work but it should give you guidance.
It will work better in an interrupt routine but you may not be ready for that yet. Also a reset timer would be good to kick me out of the routine if I geet an "A" as noise and no other "noise" comes in before the real signal but then that is another reason to have the preamble of "1"s at the beginning.
I have now tried to implement these preamble codes to ensure that the transmitted data is decoded properly. However i am having compilation problems with the decoder. MikroC is returning errors such as "Pointer Required" and "Internal Error" at the lines where arrays are declared. I tried using

Code: Select all

rxdata[rxchar] = USART_Read();
however just more errors arose. I dont know what exactly is the problem. Here is my Decoder code:

Code: Select all

unsigned short data, i, rxdata;
unsigned int rxchar;

void main() {
  CMCON = 7;          // Comparators off

  TRISA = 0;          // set PORTA to be output
  PORTA = 0xFF;       // initialize PORTA


  // Initialize USART module (8 bit, 2400 baud rate, no parity bit..)
  Usart_Init(4800);
  
  while (1) {
     if (USART_Data_Ready()) {            // if data is received
       i = USART_Read();                  // read the received data
       if (i == 65) {                  // is it and "A" ?
         rxchar = 0;
         while (rxchar < 3)  {
            if (USART_Data_Ready()) {
             rxdata[rxchar] = USART_Read();
             rxchar ++;
             }
          } // end while(rxchar)
      }
      }
      if ((rxdata[0] == 65) && (rxdata[2] == 66)) {
         data = rxdata[1];
         rxdata[0] = rxdata[1] =rxdata[2]  = rxchar = 0;
      }
          
      if(data == 0x01){         //data input is 0001
            PORTA = 0x06;       //output:  0000 0110      FORWARD

      }else if(data == 0x02){   //data input is 0010
            PORTA = 0x09;       //output:  0000 1001      BACKWARD

      }else if(data == 0x04){   //data input is 0100
            PORTA = 0x05;       //output:  0000 0101      LEFT

      }else if(data == 0x08){   //data input is 1000
            PORTA = 0x0A;       //output:  0000 1010      RIGHT

      }else{
            PORTA = 0x00;       //output:  0000 0000
      }
          
     } // end while
  
}//~!

drdoug
Posts: 1074
Joined: 16 Aug 2007 03:49
Location: St. Louis, MO

#39 Post by drdoug » 18 Jul 2008 04:53

I think there are problems with calling USART_Ready inside the two "if" statements I think the guy that wrote that code is an amateur :oops:

I found this code that I think I am using ( I need to save my files with better organization).

Code: Select all

unsigned short rxcount, rxchar, command, light = 0, chirp = 0;
 unsigned short i, j, readit;
 unsigned short t[10] = {5,6,7,8,9};

void interrupt() {
   if (PIR1.RCIF) {
      rxchar =  USART_Read();

     if (rxchar == 35) j = 0;
     else {
       t[j] = rxchar;
       j ++;
       if (j >=6) j = 0;
       }
     if ((t[0] == 65) && (t[3] == 66)) {
       if ((t[1] == PORTC) && (t[2] == 49)) light = 1;
       if ((t[1] == PORTC) && (t[2] == 50)) chirp = 1;
       if ((t[1] == PORTC) && (t[2] == 51)) {
           light = 0;
           chirp = 0;
           }
       }
      PIR1.RCIF = 0;
    }  // end   if (PIR1.RCIF)


}    // endinterrupt
I modified the code below to something I think you would want. Double check this since I am tired and it is untested.

Code: Select all


unsigned short rxcount, rxchar, i, j, readit
unsigned short t[7];

void interrupt() {
   if (PIR1.RCIF) {
      rxchar =  USART_Read();

     if (rxchar == 35) j = 0;
     else {
       t[j] = rxchar;
       j ++;
       if (j >=6) j = 0;   // too many bytes clear buffer
       }
      PIR1.RCIF = 0;
    }  // end   if (PIR1.RCIF)
}    // endinterrupt

void main() {
  CMCON = 7;          // Comparators off

  TRISA = 0;          // set PORTA to be output
  PORTA = 0xFF;       // initialize PORTA
  INTCON.GIE = 1;   // enable global interrupts
  INTCON.PEIE = 1;  // enable peripheral interrupts  ** make sure it works for your chip
  PIE1.RCIE = 1;    // enable reception interrupt  ** make sure it works for your chip

  // Initialize USART module (8 bit, 4800 baud rate, no parity bit..)
  Usart_Init(4800);

  while (1) {

      if ((rxdata[0] == 65) && (rxdata[2] == 66)) {
         data = rxdata[1];
         rxdata[0] = rxdata[1] =rxdata[2]  = rxchar = 0;
      }

      if(data == 0x01){         //data input is 0001
            PORTA = 0x06;       //output:  0000 0110      FORWARD

      }else if(data == 0x02){   //data input is 0010
            PORTA = 0x09;       //output:  0000 1001      BACKWARD

      }else if(data == 0x04){   //data input is 0100
            PORTA = 0x05;       //output:  0000 0101      LEFT

      }else if(data == 0x08){   //data input is 1000
            PORTA = 0x0A;       //output:  0000 1010      RIGHT

      }else{
            PORTA = 0x00;       //output:  0000 0000
      }

     } // end while

}//~!
I hope this helps.
Also, I did not check what chip you are using but is RA3 input only?

atommic22
Posts: 24
Joined: 17 May 2008 12:39

#40 Post by atommic22 » 18 Jul 2008 05:18

Sorry, correction: I'm using a 16F628A. In the decoder i'm using PORTA as an output. I will test your codes today and let you know how it turns out. Thanx again,

drdoug
Posts: 1074
Joined: 16 Aug 2007 03:49
Location: St. Louis, MO

#41 Post by drdoug » 18 Jul 2008 05:28

In the code example you appear to be assigning PORTA a value for testing purposes??

Code: Select all

      if(data == 0x01){         //data input is 0001
            PORTA = 0x06;       //output:  0000 0110      FORWARD 
I think this is OK since RA5 is MCLR and input only. RA4 is open drain though.

Good luck.

atommic22
Posts: 24
Joined: 17 May 2008 12:39

#42 Post by atommic22 » 18 Jul 2008 05:57

Im simply following the ports used in the schematic posted earlier in the thread. Im not sure what "open drain" means.
Also, the code you psted seems logical but im not clear on some of the particulars. For example, what does PIR1.RICF mean? Also, the 16F628 does not have PORTC.

drdoug
Posts: 1074
Joined: 16 Aug 2007 03:49
Location: St. Louis, MO

#43 Post by drdoug » 18 Jul 2008 13:23

PIR1.RCIF is the UART received data flag that becomes active when the receive buffer has data in it. PIE1.RCIE enables the flag bit for interrupt. Consult section 12.4.2 for more info.

The PORTC I used in the top code example was just pulled straight from my program and I think it works. I use PORTC as an address port. I just put a dip switch on it for address setting without havinge to change the firmware. You should try to get the bottom code example to work for your code since I "cleaned out" my junk.

atommic22
Posts: 24
Joined: 17 May 2008 12:39

#44 Post by atommic22 » 06 Aug 2008 10:34

I'm having trouble implementing start and stop bits. The code I'm using makes sense however when i program the PICs it simply doesnt work.

Encoder:

Code: Select all

void main() {
CMCON = 7;             // turns of the analog comparators on the PORTA pins
                       // ensures pins are reading digital
TRISA = 0xFF;          // set PORTA to be input

// Initialize USART module
Usart_Init(4800);

  do {
     USART_Write(49);       // 1   - preamble/sync byte
     USART_Write(49);       // 1  - preamble/sync byte
     USART_Write(49);       // 1  - preamble/sync byte
     USART_Write(65);       // A  - Look for this byte as the start of your data
     USART_Write(PORTA);   // Your Data
     USART_Write(66);       // B - Look for this byte as the end of your data
     USART_Write(35);       // # - push one more byte through
     Delay_ms(45);          // my project worked better with this delay here?
  } while (1);
}//~!

Decoder:

Code: Select all

unsigned short data, i, rxdata[3] = {0,0,0};
unsigned int rxchar;

void main() {
  CMCON = 7;          // Comparators off

  TRISA = 0;          // set PORTA to be output
  PORTA = 0xFF;       // initialize PORTA


  // Initialize USART module (8 bit, 2400 baud rate, no parity bit..)
  Usart_Init(4800);
  
  while (1) {
     if (USART_Data_Ready()) {            // if data is received
       i = USART_Read();                  // read the received data
       if (i == 65) {                  // is it and "A" ?
         rxchar = 0;
        }
        while (rxchar < 3)  {
            if (USART_Data_Ready()) {
             rxdata[rxchar] = USART_Read();
             rxchar ++;
             }
          } // end while(rxchar)
      }
      if ((rxdata[0] == 65) && (rxdata[2] == 66)) {
         data = rxdata[1];
         rxdata[0] = rxdata[1] =rxdata[2]  = rxchar = 0;
      }
          
      if(data == 0x01){         //data input is 0001
            PORTA = 0x06;       //output:  0000 0110      FORWARD

      }else if(data == 0x02){   //data input is 0010
            PORTA = 0x09;       //output:  0000 1001      BACKWARD

      }else if(data == 0x04){   //data input is 0100
            PORTA = 0x05;       //output:  0000 0101      LEFT

      }else if(data == 0x08){   //data input is 1000
            PORTA = 0x0A;       //output:  0000 1010      RIGHT

      }else{
            PORTA = 0x00;       //output:  0000 0000
      }
          
     } // end while
  
}//~!
I've tried debugging so many times and it just refuses to work and i've checked the clock settings, they are correct.

drdoug
Posts: 1074
Joined: 16 Aug 2007 03:49
Location: St. Louis, MO

#45 Post by drdoug » 06 Aug 2008 12:39

Did you try to hook up the transmitter and receiver to a terminal program to verify you are sending and receiving the correct data?

Post Reply

Return to “mikroC General”