Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 while(1) { // Servomotor LOWER 270° : TOWER PRO M996R (270°) Init_Timer2(); Init_Timer0(); p0 = &TMR0; joystick_X = (ADC_read(0)); // Reads Y axis value with channel 0 (AN0) on pin #2. //if ((joystick_X <= 500) && (joystick_X > 0)) if ((joystick_X <= 500) && (joystick_X > 100)) { //consigne_0 = 256 - 226; // consigne_0 = 256 - 226 => 226 à 256 = 30 x 1 uS = 30 uS = 0,03 mS. // ROTATION CONTINUE DROITE. //consigne_0 = 256 - (0.25 * joystick_X); consigne_0 = joystick_X / 4; //consigne_0 = joystick_X / 5; sprintl(*p0, "%3u", consigne_0); Init_Timer2(); Init_Timer0(); while(cnt0 < (consigne_0 / 10)) { portd.b1 = 0; portd.b0 = 1; // Servomotor LOWER ON. portc.b2 = 1; // LED ON. } portd.b0 = 0; portc.b2 = 0; } //if ((joystick_X >= 524) && (joystick_X < 1024)) if ((joystick_X >= 524) && (joystick_X < 924)) { //consigne_0 = 256 - 156; // consigne_0 = 256 - 156 => 156 à 256 = 100 x 1 uS = 100 uS = 0,1 mS. // ROTATION CONTINUE GAUCHE. //consigne_0 = 256 - (0.25 * joystick_X); consigne_0 = joystick_X / 4; //consigne_0 = joystick_X / 5; sprintl(*p0, "%3u", consigne_0); Init_Timer2(); Init_Timer0(); while(cnt0 < (consigne_0 / 10)) { portd.b1 = 0; portd.b0 = 1; // Servomotor LOWER ON. portc.b2 = 1; // LED ON. } portd.b0 = 0; portc.b2 = 0; } if ((joystick_X > 500) && (joystick_X < 524)) { portd.b1 = 0; portd.b0 = 0; portc.b2 = 0; } // Servomotor UPPER 360° : TOWER PRO M996R (360°) (Ancien 270° avec les 2 butées détruites) Init_Timer2(); Init_Timer1(); p1 = &TMR1L; joystick_Y = (ADC_read(1)); // Reads Y axis value with channel 1 (AN1) on pin #3. //if ((joystick_Y <= 500) && (joystick_Y > 250)) if ((joystick_Y <= 490) && (joystick_Y > 250)) { portd.b0 = 0; consigne_1 = 65535 - 1500; // consigne_1 = 65535 - 1500 => 64035 à 65535 = 1500 x 1 uS = 1,5 mS = Ton. // ROTATION CONTINUE GAUCHE LENTE. sprintl(*p1, "%5u", consigne_1); // In Library Manager check box Sprintl and check box C_Type are selected automatically. Delay_ms(1000); // Délais AJUSTABLE pour définir l'angle de rotation. } if ((joystick_Y <= 250) && (joystick_Y > 0)) { portd.b0 = 0; consigne_1 = 65535 - 1750; // consigne_1 = 65535 - 1750 => 63785 à 65535 = 1750 x 1 uS = 1,75 mS = Ton. // ROTATION CONTINUE GAUCHE RAPIDE. sprintl(*p1, "%5u", consigne_1); // In Library Manager check box Sprintl and check box C_Type are selected automatically. Delay_ms(1000); // Délais AJUSTABLE pour définir l'angle de rotation. } //if ((joystick_Y >= 524) && (joystick_Y < 774)) if ((joystick_Y >= 534) && (joystick_Y < 774)) { portd.b0 = 0; consigne_1 = 65535 - 1400; // consigne_1 = 65535 - 1400 => 64135 à 65535 = 1400 x 1 uS = 1,4 mS = Ton. // ROTATION CONTINUE DROITE LENTE. sprintl(*p1, "%5u", consigne_1); // In Library Manager check box Sprintl and check box C_Type are selected automatically. Delay_ms(1000); // Délais AJUSTABLE pour définir l'angle de rotation. } if ((joystick_Y >= 774) && (joystick_Y < 1024)) { portd.b0 = 0; consigne_1 = 65535 - 1250; // consigne_1 = 65535 - 1250 => 64285 à 65535 = 1250 x 1 uS = 1,25 mS = Ton. // ROTATION CONTINUE DROITE RAPIDE. sprintl(*p1, "%5u", consigne_1); // In Library Manager check box Sprintl and check box C_Type are selected automatically. Delay_ms(1000); // Délais AJUSTABLE pour définir l'angle de rotation. } //if ((joystick_Y > 500) && (joystick_Y < 524)) if ((joystick_Y > 490) && (joystick_Y < 534)) //if ((joystick_Y > 250) && (joystick_Y < 774)) { portd.b0 = 0; portd.b1 = 0; portc.b2 = 0; } }
joystick_X = (ADC_read(0));
if ((joystick_X <= 500) && (joystick_X > 5))
{
// ROTATION CONTINUE DROITE.
.....
// consigne_0 = joystick_X / 4;
consigne_0 = 100 + (joystick_X/10) ; // so 100 + (0 to 50) => x 10uS => 1mS à 1,5mS
.....
if ((joystick_X >= 512) && (joystick_X < 1012))
{
// ROTATION CONTINUE GAUCHE.
//consigne_0 = joystick_X / 4;
consigne_0 = 150+(joystick_X-512) / 10; // so 150 +(0 to 50)=>*10µS => 1.5 à 2mS
......
if ((joystick_X > 500) && (joystick_X < 512))
{
portd.b1 = 0;
portd.b0 = 0;
portc.b2 = 0;
}
Bonjour Paul,hello,
you don't need to built the command signal into the main , if allready done inside interrupts ..
at least only ADC reading are inside the main loop.
we have to discuss about that ..
instead to post a *.txt file
could you post a *.zip
wich contains all the project :
*.mccpi
*.cfg
*.log
*.c
*ihex ( if EEPROM used )
so, to be able to rebuild the *.hex with same conditions
for testing purpose ..
Bonjour Paul,
Even with your explanations I have no idea how to do yet. I will need your help again. While waiting for your answer I will try on my side ...
Here attached the zip file.
Merci beaucoup !
Merci beaucoup Paul !Ok, i will have a look ... entre 2 etapes du TDF ...
Hello Everybody,
Tour De France
TDF Restart today 16em Etape
unfortunatly, no French in TOP 10 general ranking !
Thanks for your help HexReader.Your code is hard to read and hard for me to understand, let alone try to fix.
For my own amusement, I wrote code from scratch. MikroC project attached.
I make no claims to the quality or reliability of the code, but it appears to work as long as I use separate power supplies for servos compared to PIC board (but common ground)
Fell free to use or ignore as you please....
after changes :
unsigned int ADC_read(unsigned char channel)
// Si message d'erreur "'ADC_read' Identifier redefined" pendant compilation, dans Library Manager décocher ADC_Read.
// ADC_read est ma propre routine écrite pour apprentissage. Je n'utilise pas ADC_Read de la librairie Mikroelektronika.
{
static unsigned int k; // Variable locale.
ADCON0 = 0x41 | (channel<<2); // ADCON0 = 01000001
// & 11000011 (masque)
// ADCON0 = 01000001
// masque :
// b0 = 1 (ADON) : pour prendre en compte l'état du convertisseur A/D, en service (0) ou à l'arrêt (1).
// b1 = 1 (GO/DONE) : pour prendre en compte l'état de la conversion A/D, en cours (1) ou terminée (0).
// b2 = b3 = b4 = b5 = 0 (CHS0 CHS1 CHS2 CHS3) : pour re initialiser au premier canal de conversion, le canal 0 (CHS0 = CHS1 = CHS2 = CHS3 = 0).
// b6 = b7 = 1 (ADSC0 ADSC1) : pour prendre en compte la valeur du diviseur, de la vitesse de conversion, choisi.
// Décalage channel de 2 bits à gauche pour placer la valeur de channel dans bits b2 b3 b4 b5 (CHS0 CHS1 CHS2 CHS3).
Delay_us(100); // Délais de 2 mS minimum. >>> A ajuster si besoin. <<<
ADCON0.GO_DONE = 1; // Déclenchement de la conversion A/N. via ADCON0.b2 = 1;
_asm NOP; // Recommandé par Microchip.
while (ADCON0.GO_DONE == 1); // Attendre que le bit GO.DONE passe à 0.
k = ADRESH <<8;
k= k | ADRESL;
return(k);
}
measures with SQA analyser
PWM1_high_time Pulse duration
16 630 µS
32 759 µS
---------- usefull range , 128 step for 270° -----
64 1.034 mS
128 1.547 ms ----- center position
192 2.066 ms
--------------------------------
224 2.318 ms
i will test your new version with SQA analyser ...
void Interrupts() iv 0x0004 ics ICS_AUTO
//void Interrupt()
{
unsigned int TMR1_value; // temporary calculation value
if ( (TMR0IE_bit==1) && (TMR0IF_bit) )
... etc
KlausST said:with an input clock of about 50kHz ...125kHz an 8 bit timer should work to generate 1ms ... 2ms pulses with good resolution
I don´t understand. 100kHz means 100 pulses per ms. thus from 1ms to 2ms there should be 100 pulses of resolution.100Khz Timer0 1ms=> 231 2mS=> 206 => range in 25 steps
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?