CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

rs232 LED BLINK pıc-to-pıc communication
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Wed Mar 15, 2023 2:00 am     Reply with quote

No. The key is this:

data=getc();

This _sits and waits for a character_. While the code is sitting here, nothing
else happens.

Now if you want the loop to keep running until a character arrives, then you
need:
Code:

    if (kbhit())
        data=getc();

Which will only call the read, when there is a character ready.

As others have said though, you really should be using the serial interrupt
to read the character. The problem with your current approach is that if
a couple of characters arrive while the code is sitting in the long delays,
after the second character, data will be lost and an overflow will happen.
Look at the example ex_sisr.c
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PostPosted: Wed Mar 15, 2023 12:28 pm     Reply with quote

Ttelmah wrote:
No. The key is this:

data=getc();

This _sits and waits for a character_. While the code is sitting here, nothing
else happens.

Now if you want the loop to keep running until a character arrives, then you
need:
Code:

    if (kbhit())
        data=getc();

Which will only call the read, when there is a character ready.

As others have said though, you really should be using the serial interrupt
to read the character. The problem with your current approach is that if
a couple of characters arrive while the code is sitting in the long delays,
after the second character, data will be lost and an overflow will happen.
Look at the example ex_sisr.c


While the data being lost, why other leds blink?
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 15, 2023 12:53 pm     Reply with quote

do a simple test...
change the 'transmitter' code to send a known sequence
say...

top:
r
delay 1/2 second
g
delay 1/2 second
b
delay 1/2 second
g
delay 1/2 second
goto top:

what colors or sequence isn't important , it just has to be KNOWN and repeated, with a small delay between them.

run and observe what the 'receiver' does......

if the receiver does exactly what the transmitter does, then not a 'receiver' problem
however I'd still be using an ISR/buffer like the exsisr.c program.
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PostPosted: Sun Mar 19, 2023 6:21 am     Reply with quote

Hiii, I want to send data using potentiometer adc conversion and want to read it from another pic. I want to control the rc servo(hobby sg90) 0 to 180 degree.I tried these codes.The servo is jittering and uncontrollable.Any easy trick or something else ? What steps should I follow? I wired tx-rx and rx-tx as previous post
TX
Code:
#include <16F877A.h>
#device adc=8
#FUSES HS, NOWDT,NOPROTECT, NOPUT , NOLVP,  BROWNOUT               
#use delay(clock=20000000)
#use rs232(baud=4800,BITS=8, PARITY=N,XMIT=pin_C6, RCV=pin_C7, STREAM=SPIC)


void main()
{
       setup_adc_ports(AN0);
       setup_adc(adc_clock_internal);
 
       
   while(TRUE)
   {
     set_adc_channel(0);
     delay_us(2);
     unsigned int8 valor_adc=read_adc(ADC_START_ONLY);
   fprintf(SPIC,"%u\r\n",valor_adc);
   // fprintf(SPIC,"%u\r\n",valor_adc);

   }

}


RX
Code:
#include <16F877A.h>
#FUSES HS, NOWDT,NOPROTECT, NOPUT , NOLVP,  BROWNOUT               
#use delay(clock=20000000)
#use rs232(baud=4800,BITS=8, PARITY=N,XMIT=pin_C6, RCV=pin_C7, STREAM=SPIC)
#use standard_io(D)

#define use_servo_1 
#define  servo_1 pin_d0
#include <servo_st.c>
#include <map_function.c>
void main()
{
     
 
       servo_init();
   while(TRUE)
   {
     
     unsigned int8 valor =getc();
     unsigned int8 valor_a=map(valor ,0,255,0,180);
 
     servo_1_write(valor_a);
     
   }

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Sun Mar 19, 2023 7:51 am     Reply with quote

ADC_CLOCK_INTERNAL is not recommended above a frequency of 1MHz.
For 20MHz, you should be using /32. Then Select the channel outside the
loop, not inside the loop. Tacq on this ADC is 20uSec, not 2. You don't
want to have to do this every time round the loop.
Then you are not actually reading the ADC correctly. You are starting
it, but not waiting for it to read. read_adc(); //with no value.
Is the correct setting to start and read the ADC.

Not surprising that the value is stupid.
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 19, 2023 8:54 am     Reply with quote

hmm, the way I read the code he sends

value
carriage return
newline

that's 3 bytes .....

so....
when he receives
getc() will receive
value
carriage return
newline

I'm pretty sure getc() does see CR and NL as valid 'characters'. In the manual for GETC(), it shows an if==13 being used......

needs to add ERRORS to the #USE RS232 (...options...).
should have a delay in the transmitting program between character sent.
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PostPosted: Sun Mar 19, 2023 12:06 pm     Reply with quote

Jittering no more exist but still uncontrollable. It works by his own. What need I do to work properly?

tx
Code:
#include <16F877A.h>
#device adc=8
#FUSES HS, NOWDT,NOPROTECT, NOPUT , NOLVP,  BROWNOUT               
#use delay(clock=20000000)
#use rs232(baud=4800,BITS=8, PARITY=N,XMIT=pin_C6, RCV=pin_C7, STREAM=SPIC,ERRORS)


void main()
{
       setup_adc_ports(AN0);
       setup_adc(ADC_CLOCK_DIV_32);
       set_adc_channel(0);
       delay_us(20);
   while(TRUE)
   {
     
     
     unsigned int8 valor_adc=read_adc();
     delay_ms(2000);
     fprintf(SPIC,"%u\r\n",valor_adc);   
     
   }

}


rx
Code:
#include <16F877A.h>
#FUSES HS, NOWDT,NOPROTECT, NOPUT , NOLVP,  BROWNOUT               
#use delay(clock=20000000)
#use rs232(baud=4800,BITS=8, PARITY=N,XMIT=pin_C6, RCV=pin_C7, STREAM=SPIC,ERRORS)
#use standard_io(D)

#define use_servo_1 
#define  servo_1 pin_d0
#include <servo_st.c>
#include <map_function.c>
void main()
{
     
 
       servo_init();
   while(TRUE)
   {
     
     unsigned int8 valor =getc();
     unsigned int8 valor_a=map(valor ,0,255,0,180);
 
     servo_1_write(valor_a);
     
   }

}
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 19, 2023 12:27 pm     Reply with quote

I'd change...

fprintf(SPIC,"%u\r\n",valor_adc); \\sends 3 bytes

to

fprintf(SPIC,"%u",valor_adc); \\only send adc value
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PostPosted: Sun Mar 19, 2023 12:55 pm     Reply with quote

temtronic wrote:
I'd change...

fprintf(SPIC,"%u\r\n",valor_adc); \\sends 3 bytes

to

fprintf(SPIC,"%u",valor_adc); \\only send adc value


Working style haven't been changed, I also tried

fputc(valor_adc,SPIC);

...
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 19, 2023 4:38 pm     Reply with quote

ok, breakdown your 'receive' program. have it send 4 known values, say 01,64,128,255.delay 1/2 second between them and 1 second after 255 as the 'received' data to the servo.
observe what the servo does.

it probably should be
full left
1/2 left
center
full right

if this works, then have the 'transmitter' send the SAME set of data, you should get the same responses.
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 4:33 am     Reply with quote

temtronic wrote:
ok, breakdown your 'receive' program. have it send 4 known values, say 01,64,128,255.delay 1/2 second between them and 1 second after 255 as the 'received' data to the servo.
observe what the servo does.

it probably should be
full left
1/2 left
center
full right

if this works, then have the 'transmitter' send the SAME set of data, you should get the same responses.


I tried this, just stands at one point
Code:
#include <16F877A.h>
#FUSES HS, NOWDT,NOPROTECT, NOPUT , NOLVP,  BROWNOUT               
#use delay(clock=20000000)
#use rs232(baud=4800,BITS=8, PARITY=N,XMIT=pin_C6, RCV=pin_C7, STREAM=SPIC,ERRORS)
#use standard_io(D)

#define use_servo_1 
#define  servo_1 pin_d0
#include <servo_st.c>
#include <map_function.c>
void main()
{
     
 
       servo_init();
   while(TRUE)
   {
       
     unsigned int8 valor =getc();
      if(valor ==1){
       
       servo_1_write(0 ); 
               
                  }
           delay_ms(500);
      if(valor ==64){
         
        servo_1_write(60);
               
                  }
          delay_ms(500);
      if(valor ==128){
       
        servo_1_write(120);
            
                  }
          delay_ms(500);
      if(valor ==255){
         
        servo_1_write(180 );
               
                  }
          delay_ms(500);
       
     
   }

}
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 5:04 am     Reply with quote

you need to delete the 'get data from transmitter' code
( unsigned int8 valor =getc();
as well as the conditionals ( if(valor ==1){ ....

and turn the 'receive' program into a 'servo tester' program.

the program should just command servo to a know position,pause,next,next ,next ,then repeat the pattern.

This actually should have been your first 'servo' program. It allows you to test the hardware, confirm the the servo driver code is good, allows you to see if the 'map' function is correct.

Once this work, THEN expand into the 'send-receive' programs
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 5:17 am     Reply with quote

temtronic wrote:
you need to delete the 'get data from transmitter' code
( unsigned int8 valor =getc();
as well as the conditionals ( if(valor ==1){ ....

and turn the 'receive' program into a 'servo tester' program.

the program should just command servo to a know position,pause,next,next ,next ,then repeat the pattern.

This actually should have been your first 'servo' program. It allows you to test the hardware, confirm the the servo driver code is good, allows you to see if the 'map' function is correct.

Once this work, THEN expand into the 'send-receive' programs


I have already done control with a potentiometer(0to180 degree).It works well but I can't control using rs232.

Code:
#include <16F877A.h>
#device adc=8
#FUSES HS, NOWDT,NOPROTECT, NOPUT , NOLVP,  BROWNOUT               
#use delay(clock=20000000)
//#use rs232(baud=4800,BITS=8, PARITY=N,XMIT=pin_C6, RCV=pin_C7, STREAM=SPIC)
#use standard_io(D)

#define use_servo_1 
#define  servo_1 pin_d0
#include <servo_st.c>
#include <map_function.c>
void main()
{
       setup_adc_ports(AN0);
       setup_adc(ADC_CLOCK_DIV_32);
        set_adc_channel(0);
       delay_us(20);
       servo_init();
   while(TRUE)
   {
     
     unsigned int8 valor_adc=read_adc();
    unsigned int8 valor_pwm=map(valor_adc,0,255,0,195);
    // fprintf(SPIC,"%u\r\n",valor_pwm);
servo_1_write(valor_pwm);
   }

}
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 7:33 am     Reply with quote

As I said before, I'd always use RDA interrupt on the receiving side, and just set flags there for the main.

Are you using a debugger to see what you received? If not, you could simply receive a character and send it out at once to a terminal. That way you can do it step by step. I get wrong characters. OK, repair that part. I get correct characters, but it doesn't work as expected. Repair that part.
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 7:39 am     Reply with quote

You big remaining issue, is using printf.

printf, is code to 'format' values into different output layouts. You are telling
it to send the value as ASCII text. So an internal value of 123, with be sent
as the text " 123". Now your receive program knows nothing about ASCII,
and read a single character. So it'll see a space, then '1', then '2', then '3'.
You need to just use 'putc' to put the single binary character representing
'123', and then the receive getc, will receive what it expects....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3, 4, 5, 6  Next
Page 2 of 6

 
Jump to:  
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