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 CCS Technical Support

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
Khansokhua



Joined: 06 Nov 2021
Posts: 92

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 10:54 am     Reply with quote

Ttelmah wrote:
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....


I did
Code:
 unsigned int8 valor_adc=read_adc( );
       putc(valor_adc);


but still same, jittering. There is a difference that motor doesn't move at max or min point of potentiometer. I also did
Code:
putc(255); // stops at 180 degree
putc(0);// other values like '0' jittering
Adc values is being read but what causes this complication? What should I do?
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 11:46 am     Reply with quote

Your servo writes take time, and have delays between then. Your putc;s
need the same.
temtronic



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

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 12:34 pm     Reply with quote

Historically, RC servos ran at 50 Hz....so you should have 20ms between commands...
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 12:40 pm     Reply with quote

I'd break everything into several parts.

Reading ADC: a few posts up I saw you are testing for exact values. Don't. There is every chance ADC will read different values for the same position of a pot. Instead use ranges, as many as you need for commands. If a pot reads between 0 and 50, that is full left. 51 - 100 something else. You get the idea. Then set a variable Command accordingly (you chose names, ranges and number of commands, of course). This can be tested with some LED's on the master PIC. If the correct LED lights up according to the pot position, this is done.

Communication: Hook the PIC's together or even hook the same PIC if it has two UART modules. Do use interrupt on the receiving side. Check if what you send appears on the receiving side and how it appears, using a buffer, debugger and one break-point or by re-sending it out on a terminal. Only my style, of course, but I'd send out short command strings, not raw ADC values. Based on a Command value, let's say FLFT. Repeat the exercise with LED's, this time on the slave side. All the parsing can be done inside isr routine, very, very fast. Main only does anything if something good arrived on the serial.
Khansokhua



Joined: 06 Nov 2021
Posts: 92

View user's profile Send private message

PostPosted: Mon Mar 20, 2023 2:12 pm     Reply with quote

temtronic wrote:
Historically, RC servos ran at 50 Hz....so you should have 20ms between commands...


Ttelmah wrote:
Your servo writes take time, and have delays between then. Your putc;s
need the same.


Uunhappily Rolling Eyes Rolling Eyes
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Tue Mar 21, 2023 1:38 am     Reply with quote

Part of this is what people have been telling you from the start.
You need to separate the receive from the update. Have a master loop,
that does the parsing, and the servo update. Running continuously.
Then have the serial receive into a buffer using the interrupt.
Each time the servo loop goes round, if a character is in the buffer it
reads this and changes the servo. If not it leaves the servo where it is.
The position then becomes stable. You send a character to move to a new
position, when you want, and when this is received, the servo moves on
the next loop. Provided you don't send movements faster than the loop,
the two operations become independant of each other.
Khansokhua



Joined: 06 Nov 2021
Posts: 92

View user's profile Send private message

#int_rda
PostPosted: Wed Mar 22, 2023 5:33 am     Reply with quote

I was trying rda interrupt, I send a constant data "putc(255);" with a button.
First press D1 led is blinking, but after more than ten push led is still blinking.
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>
int a=0;
#int_rda
void isr(){
     
    if(a>=10) {   
   output_low(pin_d1);
    a=10;

     }
   
 
if(a<10){output_high(pin_d1);
a++;}


   disable_interrupts(int_rda);
}
void main()
{
      enable_interrupts(int_rda);
      enable_interrupts(global);
     
 
       servo_init();
   while(TRUE)
   {
     delay_ms(100);
     unsigned int8 valor =getc();
     unsigned int8 valor_a=map(valor ,0,255,0,180);
     delay_ms(2000);
     servo_1_write(valor_a);
     delay_ms(2000);
   }

}
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Mar 22, 2023 11:09 am     Reply with quote

You got the RDA interrupt wrong. The received data is and must be read there, not in any loop in main(). I wrote something, see if it does the trick. Don't press the button faster then every 4 seconds, if you decide to keep both delays. Un-comment functions.
Code:

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

unsigned int8 valor = 0;
unsigned int8 valor_a;

#INT_RDA
void  RDA_isr(void)
{
valor =getc();  // read and store received data. It also clears interrupt flag.
output_toggle(pin_d1);  // turn diode on or off every time you receive something
}

void main()
{

   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
//     delay_ms(100);
//    unsigned int8 valor =getc();       // if you use interrupt, this doesn't belong here
//     valor_a=map(valor ,0,255,0,180);  // commented because I don't have that function, uncomment
     delay_ms(2000);                     // why so much delay here?
//     servo_1_write(valor_a);           // uncomment
     delay_ms(2000);
   }

}
temtronic



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

View user's profile Send private message

PostPosted: Wed Mar 22, 2023 12:26 pm     Reply with quote

comment

4800 baud is about 2ms per byte (character sent )
so if the 'transmitter' continuously sent data, it's 10X faster than what the RC servo can understand.

There is no need to send faster than 1 command every 20ms,and in fact it can 'confuse' the RC servo.
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Mar 22, 2023 12:45 pm     Reply with quote

Yes. Only me again, but I'd also do the transmitter timing via a timer interrupt. 20ms or so tick. Read ADC. Calculate the value you wish to send, send it out. But if this is the only thing master does, a loop with a delay is more than fine.
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Thu Mar 23, 2023 12:50 am     Reply with quote

Yes.
It's critical to understand that trying to do things faster than they can
actually 'happen' will actually make things occur slower rather than faster.
Khansokhua



Joined: 06 Nov 2021
Posts: 92

View user's profile Send private message

PostPosted: Thu Mar 23, 2023 1:41 pm     Reply with quote

I tried something. I though I use just two data buffered from transmitter and try compare them each other.
But it seems not going well. How can I improve this work?
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>
 
 
 
int order=0;
 
char buffer[];

#int_rda
void isr(){

   buffer[order] =getc();
   servo_init();
      delay_ms(20);
    if(buffer[order+1]==buffer[order]){

     servo_1_write(buffer[order]);
               
            }
       
    if(buffer[order+1]<=buffer[order]){

     servo_1_write(buffer[order]);
       
            }
 
    if(buffer[order+1]>=buffer[order]){

     servo_1_write(buffer[order+1]);
       
            }
order++;
if(order==2)
     order=0;
}


void main()
{
   enable_interrupts(int_rda);
   enable_interrupts(global);
     
   servo_init();
 
   while(TRUE)
   {
     
   }

}
temtronic



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

View user's profile Send private message

PostPosted: Thu Mar 23, 2023 2:56 pm     Reply with quote

1st thing. Get rid of the delay_ms(20) inside the ISR ! You should never have any delay ,of any kind in an ISR. Also no printing or 'fancy' math.
You receive a character, save it, set a 'flag', then exit.
Main() will test the 'flag' and then do whatever is necessary.

2nd thing. Use /modify the CCS supplied SISR.C code. It works and most everyone here can help.

Not to sure why you call servo_init() within the ISR. Normally an 'init' is done once at the beginning of a program.
PrinceNai



Joined: 31 Oct 2016
Posts: 480
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Mar 23, 2023 4:49 pm     Reply with quote

If I understood correctly, you are trying to control a servo over serial. I'm saying this because your questions are jumping around a bit. I have some of my own:

1. Servo motor works on your master PIC?
2. You can control servo via a pot on your master?
3. Do you receive what you send from master to slave over serial? Or better, can you read it?

About interrupts. For a property, three magic words are LOCATION, LOCATION, LOCATION. For interrupts, there are also three: SPEED, SPEED, SPEED. You don't do any delays or complicated things there, ever. No delays, no math. Your main() must do that. You dumped everything into RDA_ISR. With a 20ms delay there you could loose 10 or more commands from master and never even know it.
Khansokhua



Joined: 06 Nov 2021
Posts: 92

View user's profile Send private message

PostPosted: Fri Mar 24, 2023 5:00 am     Reply with quote

PrinceNai wrote:
If I understood correctly, you are trying to control a servo over serial. I'm saying this because your questions are jumping around a bit. I have some of my own:

1. Servo motor works on your master PIC?
2. You can control servo via a pot on your master?
3. Do you receive what you send from master to slave over serial? Or better, can you read it?



1.Servo motor works on slave
2.yes(but not expected)
3.I guess, I receive and read somethings but anormal crazy movements happen
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 3 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