|
|
View previous topic :: View next topic |
Author |
Message |
maeshlmaent
Joined: 05 Jul 2014 Posts: 3
|
robotic hand |
Posted: Sat Mar 12, 2016 6:31 am |
|
|
Hi, I'm trying to make a robotic hand with 16f877a controlled by glove probably you've seen that project with ardunio. I have some problems with coding. Can you please tell me what are my mistakes in that code.
(giris=input)
(cikis=output)
(bekle=wait)
Code: | #include <16f877.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
long int giris1,giris2,giris3,giris4,giris5, bekle1,bekle2,bekle3,bekle4,bekle5, cikis1,cikis2,cikis3,cikis4,cikis5;
void main ()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
setup_adc(adc_clock_div_32);
setup_adc_ports(ALL_ANALOG);
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL);
delay_us(20);
while(1)
{
set_adc_channel(0);
delay_us(20);
giris1=read_adc();
cikis1=((giris1*1.76)+600);
bekle1=(20000-cikis1);
output_high(pin_b0);
delay_us(cikis1);
output_low(pin_b0);
delay_us(bekle1);
set_adc_channel(1);
delay_us(20);
giris2=read_adc();
cikis2=((giris2*1.76)+600);
bekle2=(20000-cikis2);
output_high(pin_b1);
delay_us(cikis2);
output_low(pin_b1);
delay_us(bekle2);
set_adc_channel(2);
delay_us(20);
giris3=read_adc();
cikis3=((giris3*1.76)+600);
bekle3=(20000-cikis3);
output_high(pin_b2);
delay_us(cikis3);
output_low(pin_b2);
delay_us(bekle3);
set_adc_channel(3);
delay_us(20);
giris4=read_adc();
cikis4=((giris4*1.76)+600);
bekle4=(20000-cikis4);
output_high(pin_b3);
delay_us(cikis4);
output_low(pin_b3);
delay_us(bekle4);
set_adc_channel(4);
delay_us(20);
giris5=read_adc();
cikis5=((giris5*1.76)+600);
bekle5=(20000-cikis5);
output_high(pin_b4);
delay_us(cikis5);
output_low(pin_b4);
delay_us(bekle5);
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sat Mar 12, 2016 6:54 am |
|
|
comments
1) using the 877. it's old and almost obsolete. newer PICs are better and cheaper.
2) using clock speed of just 4MHz. 877 is good for 20MHz, so 5X improvement at NO cost.
3) using floating point math. NOT required and takes a VERY LONG time to process. Integer math is a lot faster and less codespace (memory) needed.
4) enabling an ISR without a handler (routine). This WILL 'loclup' or 'freeze' the PIC program, sooner or later. Do NOT enable ANY interrupts unless you have ISRs for them !
5) NOT selecting PUT fuse. NOPUT means NO Power Up Timer. I prefer to let the PIC calmly startup and PUT helps this.
6) delay_us(20) for the ADC reads is high might be able to use just 5us, which will incread overall performance (faster).
7) the delay_us(20); before main() really doesn't do a lot, could be deleted.
That's a start...
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Sat Mar 12, 2016 10:31 am |
|
|
Also note, wrong oscillator fuse. 4MHz -> XT. HS is specified for >4MHz. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Sat Mar 12, 2016 2:20 pm |
|
|
I've seen two forms of hand done with the Arduino. One using linear actuators, and the other standard servos.
Now assuming the latter, the first thing is to forget the delay after the pulse. Standard servos don't actually 'care' how long the gap between pulses is. They only look at the length of the positive pulse. This is done because the gap changes according to the type of radio being used, and even varies in some systems as channels are enabled and disabled.
Now the standard pulse to operate a servo, is 1 to 2mSec. The scales being used, make no sense. The PIC ADC returns 0 to 1023. So the values being used to scale the ADC, would give:
19400 - 0 to
19400 - 1800
So a pulse width of 19.4mSec to 17.6mSec. Totally wrong.....
For the ADC to give the full range for a servo, would require 0-1023 to give a change in pulse width of 1000 counts. In fact most servos will accept slightly more than their specified range, so the ADC value can be used directly.
Code: |
set_adc_channel(0);
delay_us(10);
giris1=read_adc();
delay_us(2012-giris1);
output_low(pin_b0);
|
Is all that is needed for each channel to make a pulse that would move the servo from end to end for a pot giving 0 to 5v.
The time needed to handle the other three channels, will then give the gap required. |
|
|
|
|
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
|