rev 16/06/2025

Test Entrees Analogiques pour parametrage Portail
avec BASE 18F27K42



1) Hardware
2) Config et mesures analogique.
3)
Reglage PWM Lent (via EA0) et PWM Rapide (via EA1)
4)
Reglage durée en Butée via EA2
5) Reglage Alerte INA221 via entree Ana EA3





1) Hardware

Prototype de test :
images3/t_Proto_4EA_Portail_2025-0617.gif

Pour ce test , j'utilise ma Base 18F27K42
Terminal YAT PC sur UART1 5C6 TXet RC7 RX , via un cordon prolific LTTL/USB
Pickit4 pour programmer le PIC
MPLABX IDE + XC8 compilateur
Alimentation 5V
Base 18F27K42 + Breadboard + Shunt 0.01 avec INA226 + IBT2 driver + LCD +3 potars
Entrées ANALOGIQUES : RA0,RA1,RA2,RA3
Sortie Led rouge : RA4
Sortie Marche IBT2 en RB6
INTB du MCP23017 sur ENtree RB0 ..non utilisée, uniquement pour le test Interrupt MCP
Liaisons bus I2C1 RC3 (SCL) RC4 (SDA) vers INA226 et le LCD 4x20 .
Liaison sortie (Alarme) ALERTE INA226 -> entree RC0 du PIC18F ( Interrupt RC0!)
Liaison ICSP <-> Pickit4
Liaison UART TX RC6 et RX RC7 (Interrupt RX) via cordon Prolific USB.TTL ... terminal PC YAT 115200bds
Alimentation du PIC et INA226 via converter DC/DC 9V---> 5V
La source de mesure de courant (Moteur ) vient d'une alim externe DC ajustable de 5 à 12V



2)Configuration et et Acquisition des 4 Mesures Analogiques
sur RA0,RA1,RA2,RA3

schema partiel ;

les resistances R4 et R5 pull up sur ma carte Base 18F27K42 sont absentes en mode entree analogique. (....utilisées en mode OWS pour DS18B20)
EA1 reliée au 0V


ADC en mode 12bits .. 0 à 4096 Pts pour 0 à 5V
4 potentiometres permettent d'envoyer une consigne sur respectivement :
RA0 consigne PWM vitesse Rapide
RA1 consigne PWM vitesse Lente
RA2 consigne Durée de blocage maxi x 0.1sec
RA3 consigne Courant Maxi en butée

mais je n'ai que 3 potars pour les tests :
Pot sur entree ANA RA0 consigne % pour PWM1 (mais pas PWM2 ..car test sur 1 seul sens de rotation)
* RA1 entree ANA..au 0V ( car en l'air perturbe un peu !)
Pot sur entree Ana RA2 pour definir la tempo sur butee 0 à 255 , en divisant la mesure par 16 ou ne lisant que le MSB .de l'ADC ..( pour 0 à 25.5sec par pas de 0.1Sec)
Pot sur entree Ana RA3 pour definir le seuil d'alert de 0 à 1023 pour 0 à 0.6Amp dans le cas present
Rappel : ... à réactualiser plus tard, la calibration pour 0 à 8,192Amps au lieu de 0 à 0,6 actuellement ..

Nota : mes commandes de %PWM via le clavier YAT sont donc ecrasées par les valeurs Potar .. (sauf PWM2 non concernée)
On peut donc inverser aussi le sens par une commande clavier de PMW2 > PMW1
La cde clavier "Marche"qui armait RB6 a été passée sur RB5 ..because probleme avec Pickit4 ,plus reconnu (et RB6 en sortie!)

SOFTWARE :

Au lancement du programme :
Dans l'init Hardware
TRISA = 0b10001111 ;// declaration sens 0=Sortie , sinon 1=entree
ANSELA = 0x0F;
// declaration voies en analogique

unsigned int EA0,EA1,EA2,EA3;

L'init generale du mode d'acquisition voies ADC

void Init_Analog(void)
{
ADCON0=0;
//CONT=0 = ADC is cleared upon completion of each conversion trigger
//CS: ADC Clock Selection bit=0 Clock supplied by FOSC, divided according to ADCLK register
ADCON0bits.FM = 1; //right justify
ADCON0bits.CS = 1; //ADCRC Clock
//ADC instable avec ADCLK => FOSC/2
//ADCLK=0;//FOSC/2 15.6nS at 64MHz
ADCLK=7;//FOSC/16 250nS at 64MHz
//ADCLK=31;//2µs at 64MHz
ADCON1=0;
ADCON2=0; //Basic mode
ADPCH = 0x00; //RA0 is Analog channel
ADCON3=0; //no interrupt
TRISAbits.TRISA1 = 1; //Set RA0 to input
ANSELAbits.ANSELA1 = 1; //Set RA0 to analog
#ifdef With_ADC_REF4096
FVRCON=0;
FVRCONbits.EN=1;
FVRCONbits.ADFVR1=1; // 4.096V au lieu de Vdd=5V
FVRCONbits.ADFVR0=1;
#endif
ADCON0bits.ON = 1; //Turn ADC On
}DCON0bits.ON = 1; //Turn ADC On
}


L'acqusition des mesures ..codage lineaire

void Mesures_Analogiques()
{
uint16_t k;
ADCON0bits.ON = 1; //Turn ADC On
ADPCH=0;// choix de Channel
asm ("nop");asm ("nop");
// 2 Nop =delai de stabilistation
ADCON0bits.GO = 1; //Start conversion
asm ("nop");
while (ADCON0bits.GO); //Wait for conversion done
k=(ADRESH <<8);
EA0=k+ADRESL;
ADPCH=1; asm ("nop");asm ("nop");
ADCON0bits.GO = 1; //Start conversion
asm ("nop");
while (ADCON0bits.GO); //Wait for conversion done
k=(ADRESH <<8);
EA1=k+ADRESL;
ADPCH=2; asm ("nop");asm ("nop");
ADCON0bits.GO = 1; //Start conversion
asm ("nop");
while (ADCON0bits.GO); //Wait for conversion done
k=(ADRESH <<8);
EA2=k+ADRESL;
ADPCH=3; asm ("nop");asm ("nop");
ADCON0bits.GO = 1; //Start conversion
asm ("nop");
while (ADCON0bits.GO); //Wait for conversion done
k=(ADRESH <<8);
EA3=k+ADRESL;
ADCON0bits.ADON=0;
};


dans le programme main :

CPrint(" Init Mesures Analogiques\r\n");
Init_Analog();
Start_Chrono();
Mesures_Analogiques();
Stop_Chrono(1);
sprintf(CRam1," EA0=%05d, EA1=%05d, EA2=%05d, EA3=%05d",EA0,EA1,EA2,EA3);
Print(CRam1);
CRLF1();

Init Mesures Analogiques
SMT1 Nb Tics 158 uS
EA0=01345, EA1=00000, EA2=02007, EA3=00294
chronometrage des 4 mesures Ana sur terminal YAT .... 158 µSec

puis dans la boucle principale :



3) Reglages Vitesse Lente et Rapide

En fait, on ne maitrise pas la vitesse ,mais la tension moyenne du moteur !
La vitesse depend de U moteur , U=E- r*I avec r=resistance d'induit et I courant en amperes.
A vide, on aura une linearité Vitesse=f(U) acceptable
.mais quid de la consommation moteur dependant de l'effort mecanique
Avec une resistance de ligne complete : R du cable + R Induit moteur => 6 Ohms
Au pire on peut avoir Vitesse Nulle avec E=28V et r*I = 6 ohms*4.6Amps....si le moteur est bloqué mécaniquement.

Les PWM sont en mode 10 bits , donc 0 à 1023 pour 0 à 100%
* conditionné par la valeur de PR2 !, car Nb de bits effectifs liée à la Frequence
Dans un premier temps on peut affecter arbitrairement 0 à 50% pour RA0 vitesse Lente
et 50 à 100% pour PWM Vitesse Rapide
La mise à l'echelle Points ANA pour la vitesse Lente -> % PWM de 0 à 512 est simple ..=>. 4096/8
EA0 0 à 4095 Pts ........PWM de 0 à 511 -> 0 à 51%
La mise à l'echelle Points ANA pour la vitesse Rapide -> % PWM de 512 à 1023 = 512+ 4096/8
EA1 0 à 4095 Pts ........PWM de 512 à 1023 -> 51 à 100%

Mesures_Analogiques();
PWML=EA0>>3 ; // 4096 / 8 = > 51.2% PWM maxi vitesse lente
PWMR=(EA1>>3)+512; => 100% maxima vitesse Rapide

Nota : pour mes tests j'ai laissé k1_PWM commande 0 à 100 % via Potar sur EA0
et k2_PW1 (initialisé à 0% , donc non lié à EA1, mais possibilité de commande via terminal YAT



4) Reglage Delai en butée


Avec une voie ANA sur 4096 points si on se contente de 127 points
et avec l’usage de la base de temps generale de 0,1mS on peut donc regler une duree de 0 à 12.7 sec
par comptage du nombre d'interrupt TimerX à 0,1sec
on pourrait aussi faire d'autres combinaisons ... 0 –127  => 0 à 12.7sec 

NbTicks_Butee= EA2 >>5;

Exemple base de temps 100 mS pour centrale clignotante :
void TMR6_Init_100ms(void)
{
PIE9bits.TMR6IE=0 ;
T6CLKCON = 0x05; // T2CS FOSC/4 ou 0x05 pour 500Khz soit T=2µS
T6HLT = 0x80; // synchro sur fosc/4
T6RST = 0x01; // restart by T6TMR Postscaled
//T6CON = 0x70 | 0x07 ; > ticks=2x1024=2048µS
T6CONbits.CKPS= 5; // Prescaler =5=>1/32
T6CONbits.OUTPS=6; //Poscaler=6=>1/7
T6PR=222; // 2µS * 32 * 7 * (223+1) =>100352 -> 100mS ou 222+1 -> 99 904µS
Flag_Timer6=0;
Drapeaux.Tmr6_Elapsed=0;
Cpt6=0;
PIR9bits.TMR6IF=0;//
PIE9bits.TMR6IE=1 ; // TMR6IE_bit=1;
TMR6ON = 1;
}

et interrupt associée

void __interrupt(irq(IRQ_TMR6),low_priority) TMR6_ISR(void)
{ //... evry 100mS ....
Cpt6++;
if (Cpt6 % 5==0) Bit500mS=!Bit500mS;
// centrale clignotante pour led
Flag_Timer6=1;
T6PR=222; // pour 100mS
PIR9bits.TMR6IF=0;// clear the TMR6 interrupt flag

}

pour utiliser la duree de delay en butée

En debut de programme :
TMR6_init();

// test reglage Duree butee
si
#def ineTest_potar_Delay_Butee activé
test en boucle infinie,affiche la due sous frome de . (chaque 100mS) en fonction du reglage Potar sur EA2



resultat visuel sur YAT terminal :

images3/t_Capture_Reglage_duree_butee_EA2.gif



5) Reglage Seuil de courant Alert INA via EA3

Details sur Mesure INA1 ici

En Résumé :
Module INA226 sur un shunt de 0.01 ohms (15Amps 150mV classe 0,5)
liaisons :
Shunt coté High End (point chaud alim du Moteur (12 ou 28V))..
alim module INA +5V et Gnd,
Bus I2C1 : RC3 SCL et RC4 SDA, PIC18F
sortie : ALERT sur inp RC0 , PIC18F

../_INA226_Tests/images/t_INA229_sur_Shunt_150mV_15Amps.gif

regsitres INA226 :
INA226_BUS_REG 0x02 //Bus Voltage Register
INA226_SHUNT_REG 0x01 //Shunt Voltage Registere
INA226_BUS_REG
INA226_CURRENT_REG

La valeur du seuil de courant est conditionné par la relation
32768 points pour 81,92mV sur un shunt de 0,01 ohms ..soit 8,192Amps
pour un seuil d'ALERT à 6A => seuil = 32768 * 6.0 /8.192 .=> 24000 pour 6Amps
Le potar EA3 de 0 à100% delivre 0 à 4095 points
4096 * 6 => 24576 points => 6.144AmpsEn prenant 24576 points le coeff de mise à l'echelle est un entier =6
evite de manipuler des flottants 32 bits et calculs...
Usage de decalages logiques au lieu de Multiplication..

uint16_t k; // variable intermediare
k=(EA3<<1);// multiplie EA par 2
k=k+ (EA3<<2). // puis rajoute multiplie EA par 4 ,... donc 6 fois

Mais il faut Informer l'INA226 de cette modif ..
Nota : Auparavant, cette modif pouvait AUSSI etre faite directement via le terminal YAT
..sans passe par la voie analogique.

Le meme traitement est appliqué

// Alert MASK_EN_REG register 07h <- 2400 pour 0.6 A
// 2400 pour 0.6Amps
// 24000 pour 6Amps
k contient la valeur du seuil en point
tmp[0]=INA226_ALERT_LIMIT_REG;
tmp[1]=(k >> 8);
tmp[2]=(uint8_t)(k & 0x00FF);
Addr=INA226_ADDR;
p1=&tmp[0];
cx=3;
I2C1_WriteNBytes(Addr, p1, cx);


On relit le registre , à un autre moment dans la boucle principale,
pour afficher la valeur en unites physiques : en Amperes ..sur terminal ou LCD

Addr= INA226_ADDR;
tmp[0]=0;
tmp[1]=0;
p1=&tmp[0];
I2C1_ReadDataBlock(Addr, INA226_ALERT_LIMIT_REG, p1,3);
k=(tmp[0]<<8) + tmp[1];
//Seuil_Alerte= 8.192 * (double)k / 32768.0;
Seuil_Alerte= (double)k / 4000.0;
// simplification de calcul
sprintf(CRam1," Seuil d'alerte %3.3f Amperes\r\n",Seuil_Alerte);
// pour affichage en Ampere
Print(CRam1);
CRLF1();


On pourrait donc regler "En live" l'alarme courant ALERT ....
mais dans mon test je lance une commande YAT : SET INA1 ALERT via EA3 pour que la valeur de EA3
soit prise en compte... car dans l'application finale,il faudra etre dans un certain Phase-Pas du programme
pour permettre ce changement.

Nota: pour le forçage en butée , le courant sera forcement maximal !
=> ALERT générée ...mais devra etre inhibée pendant la duree du temps reglé via potar EA2 Delay_Butee
sinon en "marche normale" ALERT => arrzet moteur

Capture terminal YAT :
images3/t_Capture_YAT_2025-0617.gif

derniere modif : inclusion en direct Live du reglage Alert( Amperes)et reglage duree Butee ( x 100mS)
Terminal_pour_Test_portail_2025-0616.yacp



SOFTWARE :

Environnement MPLABX IDE + XC8 compilateur
Programmateur : Pickit4

18F27K42_PMW_INA226_MCP23017_2025-0618.X.zip
main_18F27K42_PMW_INA226_MCP23017_2025-0618.X.c
Dialogue_UART_MCP23017_2025-06.inc




paulfjujo@free.fr