|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19249
|
|
Posted: Wed Mar 15, 2023 2:00 am |
|
|
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: 92
|
|
Posted: Wed Mar 15, 2023 12:28 pm |
|
|
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: 9127 Location: Greensville,Ontario
|
|
Posted: Wed Mar 15, 2023 12:53 pm |
|
|
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: 92
|
|
Posted: Sun Mar 19, 2023 6:21 am |
|
|
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: 19249
|
|
Posted: Sun Mar 19, 2023 7:51 am |
|
|
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: 9127 Location: Greensville,Ontario
|
|
Posted: Sun Mar 19, 2023 8:54 am |
|
|
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: 92
|
|
Posted: Sun Mar 19, 2023 12:06 pm |
|
|
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: 9127 Location: Greensville,Ontario
|
|
Posted: Sun Mar 19, 2023 12:27 pm |
|
|
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: 92
|
|
Posted: Sun Mar 19, 2023 12:55 pm |
|
|
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: 9127 Location: Greensville,Ontario
|
|
Posted: Sun Mar 19, 2023 4:38 pm |
|
|
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: 92
|
|
Posted: Mon Mar 20, 2023 4:33 am |
|
|
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: 9127 Location: Greensville,Ontario
|
|
Posted: Mon Mar 20, 2023 5:04 am |
|
|
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: 92
|
|
Posted: Mon Mar 20, 2023 5:17 am |
|
|
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: 462 Location: Montenegro
|
|
Posted: Mon Mar 20, 2023 7:33 am |
|
|
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: 19249
|
|
Posted: Mon Mar 20, 2023 7:39 am |
|
|
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.... |
|
|
|
|
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
|