Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Projet "superviseur de charge" pour batteries
djviper16
Débutant
Débutant
Messages : 38
Enregistré en : décembre 2020

#1 Message par djviper16 » dim. 6 juin 2021 23:20

Bonsoir,

Depuis la dernière fois sur ce forum j'ai continué d'en apprendre sur la programmation des PICs avec quelques petits projets, notamment la réalisation d'un superviseur de charge.

Il fait une mesure de la tension aux bornes des batteries toutes les 15 minutes, et si nécessaire active et relaye le chargeur vers la batterie en besoin, pendant 30 minutes. Le PIC utilisé est un classique 16F684. Les 4 batteries peuvent être indépendantes ou en série, et pour ce faire j'ai clairement copié le câblage des relais du schéma de Mr P. DEMERLIAC ici : http://philippe.demerliac.free.fr/Misc.htm#CP46

Je souhaiterais perfectionner ce projet, hors cette fois-ci je mets la barre vraiment plus haut. Ecran OLED SSD1306 128x64 et ADCs qui communiqueront en SPI avec le PIC via quadruples optocoupleurs, détection du nombre de batteries connectées, comptage du nombre de cycles de charge, réglage de la tension de déclenchement de la charge, réglage du délais entre chaque contrôle de tension, arrêt du chargeur lorsque la tension paramétrée est atteinte, etc.

Pour mener à bien ce projet je prévois de passer de MPLAB IDE v8.91 à MPLAB X. Et j'ai commandé un pickit4 chez Microchip pour remplacer mon pickit2 asiatique actuel. Je pense aussi passer de CCS à un compilateur Microchip pour bénéficier de MCC. XC8 ?

Bref, première question qui se pose : quel PIC utiliser pour ce projet ? Il semble être temps pour moi d'abandonner la série 16F pour passer sur du 18F ou 24F ?

Quelques photos de ma première version fonctionnelle de ce superviseur.
Image
Image
Image

Et le code en C, certainement perfectible mais néanmoins fonctionnel.
//////////////////////////////////////////////////////////
//// CARTE SUPERVISEUR 4 BATTERIES ////
//// COMPILATEUR CCS ////
//// DEVELOPPEMENT MPLAB IDE v8.91 ////
//// 10/01/2021 ////
//////////////////////////////////////////////////////////


#include <16F684.h>

#use delay(clock=4000000) //fréquence de l'oscillateur interne : 4MHz
#fuses INTRC_IO,NOWDT,NOPUT,NOBROWNOUT,NOMCLR,NOPROTECT,NOCPD,NOPUT,NOIESO,NOFCMEN,BROWNOUT_NOSL //il faut tous les mettre sinon ça marche pas
#use fast_io(A) // permet d'utiliser set_tris_X(), sinon CCS affecte automatiquement les ports.
#use fast_io(C) // permet d'utiliser set_tris_X(), sinon CCS affecte automatiquement les ports.



#byte ANSEL = 0x91
#byte CMCON0 = 0x19
#byte ADCON0 = 0x1F
#byte ADCON1 = 0x9F
#byte ADRESH = 0x1E
#byte ADRESL = 0x9E

//////ADRESSES PORTS ET BITS E/S//////
#byte portA=5 //adresse du port A
#byte WPUA=95 //adresse WPUA
#byte IOCA=96 //adresse IOCA
#bit RAPU = 0x81.7
#byte portC=7 //adresse du port C


#bit relais_bat_4=portA.0 //affectation du RA0
#bit relais_bat_3=portA.1 //affectation du RA1
#bit relais_bat_2=portA.2 //affectation du RA2
#bit RA3=portA.3 //affectation du RA3
#bit RA4=portA.4 //affectation du RA4
#bit RA5=portA.5 //affectation du RA5

#bit relais_bat_1=portC.0 //affectation du RC0
#bit relais_chargeur_230V=portC.1 //affectation du RC1
#bit relais_chargeur_12V=portC.2 //affectation du RC2
#bit mesure_tension=portC.3 //affectation du RC3
#bit RC4=portC.4 //affectation du RC4
#bit RC5=portC.5 //affectation du RC5


//////TIMER1 REGISTRES//////
#byte INTCON = 0x0B //INTCON REGISTER adresse 10h
#byte T1CON = 0x10 //T1CON REGISTER adresse 10h
#byte TMR1L = 0x0E //TMR1L REGISTER adresse 0Eh
#byte TMR1H = 0x0F //TMR1H REGISTER adresse 0Fh
#bit TMR1IF = 0x0C.0 //adresse du bit Flag quand le timer déborde
#bit TMR1IE = 0x8C.0 //adresse du bit d'activation des interruptions
#bit GIE = 0x0B.7
#bit PEIE = 0x0B.6


//////DECLARATION VARIABLES//////
long adresult;
long ref;
int hi;
int lo;
int demisec,min,hr;

//////INTERRUPTION TIMER1//////
#int_timer1
void interrupt_timer1() //routine d'interruption Timer1 (if TMR1IF==1)
{
TMR1IF=0; //flag du Timer1 à 0
T1CON=0x34; //0b00110100 Timer1 arrêté
TMR1L=0xDB; //config précharge compteur 16 bits
TMR1H=0x0B; //0x0BDB (3035 en decimal) (pour compter de 3035 à 65535 pour avoir 0.5 seconde)
T1CON=0x35; //0b00110101 Timer1 démarré
demisec++;
if (demisec==120) {demisec=0,min++;}
if (min==60) {min=0,hr++;}
if (hr==24) {hr=0;}
}




void main()
{
//////PORTS ET BITS E/S//////
ANSEL=0x80; //entrée analogique AN7 (RC3) uniquement
ADCON0=0b10011100; //
ADCON1=0b01010000; //Fosc/16

CMCON0=0xFF; //désactive les comparateurs
SET_TRIS_A(0x00); //tout le portA en sortie
SET_TRIS_C(0x08); //tout le portC en sortie sauf RC3 -> 0b00001000
RAPU=1; //1 = PORTA pull-ups are disabled
WPUA=0x00; //0 = Pull-up disabled
IOCA=0x00; //0 = Interrupt-on-change disabled

//////VALEURS VARIABLES//////
adresult=0;
ref=0b0000001010000101; //seuil 12.61V -> 645(decimal) //20V -> 1023
demisec=0;
min=0;
hr=0;

//////TIMERS (GENERAL)//////
INTCON=0xC0; //GIE et PEIE à 1 pour activer interruptions (bits 7 et 6)du Timer1
//T0IE : 0 = Disables the TMR0 interrupt
//INTE : 0 = Disables the BP_Ton_RA2/INT external interrupt
//RAIE : 0 = Disables the PORTA change interrupt
//T0IF : 0 = TMR0 register did not overflow
//INTF : 0 = The BP_Ton_RA2/INT external interrupt did not occur
//RAIF : 0 = None of the PORTA <5:0> pins have changed state


//////TIMER1 REGISTRES//////
T1CON=0x34; //0b00110100 Timer1 arrêté
TMR1L=0xDB; //config précharge compteur 16 bits
TMR1H=0x0B; //0x0BDB (3035 en decimal) (pour compter de 3035 à 65535 pour avoir 0.5 seconde)
TMR1IF=0; //flag du Timer1 à 0
TMR1IE=1; //1 = Enables the Timer1 overflow interrupt
T1CON=0x35; //0b00110101 Timer1 démarré


//////INITIALISATION RELAIS//////
relais_bat_1=0;
relais_bat_2=0;
relais_bat_3=0;
relais_bat_4=0;
relais_chargeur_230V=0;
relais_chargeur_12V=0;



//////////////////Boucle principale/////////////////////
while(1)
{


///////////Batterie 1///////////
relais_bat_1=1;
delay_ms (5000);
ADCON0=0b10011101; //allume le can
delay_ms (10);
ADCON0=0b10011111; //démarre une conversion
delay_ms (10);
// adresult=ADRESH<<8;
// adresult=adresult|ADRESL;
hi=ADRESH;
lo=ADRESL;
adresult=make16(hi,lo);

if (adresult<=ref && adresult>153) //Si tension comprise entre 3V et ref
{
demisec=0;
min=0;
hr=0;
while (min<30) //temps de charge = 30 minutes
{
relais_chargeur_230V=1;
delay_ms (1000);
relais_chargeur_12V=1;
}
relais_chargeur_12V=0;
delay_ms (500);
relais_chargeur_230V=0;
delay_ms (500);
relais_bat_1=0;
}
else {
demisec=0;
min=0;
hr=0;
while (min<15) //temps repos entre 2 contrôles de tension = 15min
{
relais_bat_1=0;
}
}


///////////Batterie 2///////////
relais_bat_2=1;
delay_ms (5000);
ADCON0=0b10011101; //allume le can
delay_ms (10);
ADCON0=0b10011111; //démarre une conversion
delay_ms (10);
// adresult=ADRESH<<8;
// adresult=adresult|ADRESL;
hi=ADRESH;
lo=ADRESL;
adresult=make16(hi,lo);

if (adresult<=ref && adresult>153)
{
demisec=0;
min=0;
hr=0;
while (min<30) //temps de charge = 30 minutes
{
relais_chargeur_230V=1;
delay_ms (1000);
relais_chargeur_12V=1;
}
relais_chargeur_12V=0;
delay_ms (500);
relais_chargeur_230V=0;
delay_ms (500);
relais_bat_2=0;
}
else {
demisec=0;
min=0;
hr=0;
while (min<15) //temps repos entre 2 contrôles de tension = 15min
{
relais_bat_2=0;
}
}


///////////Batterie 3///////////
relais_bat_3=1;
delay_ms (5000);
ADCON0=0b10011101; //allume le can
delay_ms (10);
ADCON0=0b10011111; //démarre une conversion
delay_ms (10);
// adresult=ADRESH<<8;
// adresult=adresult|ADRESL;
hi=ADRESH;
lo=ADRESL;
adresult=make16(hi,lo);

if (adresult<=ref && adresult>153)
{
demisec=0;
min=0;
hr=0;
while (min<30) //temps de charge = 30 minutes
{
relais_chargeur_230V=1;
delay_ms (1000);
relais_chargeur_12V=1;
}
relais_chargeur_12V=0;
delay_ms (500);
relais_chargeur_230V=0;
delay_ms (500);
relais_bat_3=0;
}
else {
demisec=0;
min=0;
hr=0;
while (min<15) //temps repos entre 2 contrôles de tension = 15min
{
relais_bat_3=0;
}
}


///////////Batterie 4///////////
relais_bat_4=1;
delay_ms (5000);
ADCON0=0b10011101; //allume le can
delay_ms (10);
ADCON0=0b10011111; //démarre une conversion
delay_ms (10);
// adresult=ADRESH<<8;
// adresult=adresult|ADRESL;
hi=ADRESH;
lo=ADRESL;
adresult=make16(hi,lo);

if (adresult<=ref && adresult>153)
{
demisec=0;
min=0;
hr=0;
while (min<30) //temps de charge = 30 minutes
{
relais_chargeur_230V=1;
delay_ms (1000);
relais_chargeur_12V=1;
}
relais_chargeur_12V=0;
delay_ms (500);
relais_chargeur_230V=0;
delay_ms (500);
relais_bat_4=0;
}
else {
demisec=0;
min=0;
hr=0;
while (min<15) //temps repos entre 2 contrôles de tension = 15min
{
relais_bat_4=0;
}
}
}
}



Projet "superviseur de charge" pour batteries
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 1866
Enregistré en : juillet 2016
Localisation : Terre

#2 Message par Temps-x » lun. 7 juin 2021 00:51

Bonsoir djviper16, et tout le forum,

Pas besoin d'un Pic extraordinaire pour faire ce que tu décris, il faut juste un pic qui soit rapide et avec beaucoup de patte et de préférence facile à mettre en oeuvre, par exemple Pic18F46k22

==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Projet "superviseur de charge" pour batteries
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1906
Âge : 70
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#3 Message par paulfjujo » lun. 7 juin 2021 08:53

bonjour djviper16, et à tous

:sifflotte: le 16 c'est pour 16 cylindres ?

Temps-x a écrit :Bonsoir djviper16, et tout le forum,
Pas besoin d'un Pic extraordinaire pour faire ce que tu décris, il faut juste un pic qui soit rapide et avec beaucoup de patte et de préférence facile à mettre en oeuvre, par exemple Pic18F46k22

==> A+


il ya 1 an ,j'aurais aussi plussoyé le choix du 18F26K22 (18F46K22) qui est performant et facile à utilisé, mais
il devient obsolete et je prefere maintenant son successeur ... les 18F27K42 ( 18F47K42) car ils sont moins chers !
avec 128K program 8,2K RAM et ADC12 bits
meme si au depart il demande plus d'étude à cause de ses nouvelles fonctionlalités.
testé avec avec MPLAB X et XC8 , ça gaze ..
test OLED et RTC

tu as donc un bon sujet à suivre et tu trouvera ici une aide de tous .
Aides toi, le ciel ou FantasPic t'aideras

Projet "superviseur de charge" pour batteries
djviper16
Débutant
Débutant
Messages : 38
Enregistré en : décembre 2020

#4 Message par djviper16 » lun. 7 juin 2021 14:15

Merci pour vos réponses :-)

@pauljujo loupé, 16 c'est pour mon département :lol:
Je vais donc suivre vos conseils et m'orienter sur un 27K42 ou un 47K42. Il faut que j'étudie bien mon besoin en nombre de broches.
J'ai vu sur la doc (808 pages !!! :eek: ) que ce PIC dispose d'un oscillateur interne 64Mhz, et sur ton site on voit que tu utilises un 20Mhz externe. Il y a une raison particulière à ça ?
Pour moi l'oscillateur interne est un critère de choix, pour justement ne pas avoir besoin d'un externe.


Une question un peu "technique" me vient, il est possible de brancher l'écran OLED et 4 ADC sur le même canal SPI n'est-ce pas ?
Je n'ai jamais utilisé la communication en SPI ou I2C...

Projet "superviseur de charge" pour batteries
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1906
Âge : 70
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » lun. 7 juin 2021 14:35

djviper16 a écrit :
@pauljujo loupé, 16 c'est pour mon département :lol:


j'avais en tete :
La Dodge Viper est une voiture de sport américaine de type «muscle car» à moteur V10


djviper16 a écrit :
J'ai vu sur la doc (808 pages !!! :eek: ) que ce PIC dispose d'un oscillateur interne 64Mhz, et sur ton site on voit que tu utilises un 20Mhz externe. Il y a une raison particulière à ça ?
Pour moi l'oscillateur interne est un critère de choix, pour justement ne pas avoir besoin d'un externe.


j'ai une seule carte utilisée avec un Q=20MHz , les 4 autres sont en FOSC=64MHz interne , sans quartz, RA6 et RA7 dispo
no problemo de precision ,meme avec un UART à 115200bds

djviper16 a écrit :
Une question un peu "technique" me vient, il est possible de brancher l'écran OLED et 4 ADC sur le même canal SPI n'est-ce pas ?
Je n'ai jamais utilisé la communication en SPI ou I2C...


si Ecran OLED SS1306 en I2C et ADC en I2C ...
il faut verifier que l'ADC choisi à la possibilité de définir l'adresse device ( adresse de base + selection A0 A1 + eventuellement A2 )

exemple avec ADC MCP3424 microchip
4 voies differentielles 18 bits sur I2C avec 2 bits d'adresse => on peut donc mettre 4x 4=16 voies sur le bus I2C
le tout sur les 2 fils du bus I2C
il suffit de spécifier l'adresse I2C de l'élément choisi
nota : tu peux aussi rajouter sur le bus I2C , une RTC horloge temps reel, une EEPROM128K ...

l'ADC microchip MCP3304 8ch en SPI 12 bits multiplexées.

voir Groupage de 4 mesures 17 bits + 8 mesures 12bits + 5 mesures 10 bits + RS232.. avec un (vieux) 18F258

si Ecran OLED SPI et plusieurs ADC SPI , il y a normalement toujours une broche de CS selection de boitier à gerer par des sorties PIC
pour dialoguer avec l'élement choisi .
Aides toi, le ciel ou FantasPic t'aideras

Projet "superviseur de charge" pour batteries
djviper16
Débutant
Débutant
Messages : 38
Enregistré en : décembre 2020

#6 Message par djviper16 » lun. 7 juin 2021 22:22

Entendu merci, pour les communications je privilégie le SPI.

Mes ADCs sont des MCP3002 de chez Microchip, ils ne connaissent pas l'I2C, et j'ai vérifié ils disposent bien de la broche CS de sélection.

J'en aurai un par batterie, individuellement alimentés par celles-ci à l'aide d'une zener 5,1V. J'ai pris des 3002 plutôt que des 3001 car ils sont moins chers.

Aucune masse commune entre les ADCs pour pouvoir câbler le superviseur sur des batterie branchées en série.

Des quadruples optocoupleurs TLP293 s'occuperont d'isoler entre les ADCs et le PIC.

La navigation dans les menus se fera à l'aide d'un codeur rotatif / poussoir (je ne sais pas trop quel nom ça porte).

J'ai passé commande chez Microchip pour les 18F27k42 (j'ai quand même pris un 18F47k42 au cas où). Réception fin Juin.

Enfin, j'ai pu vérifier le bon fonctionnement de mes petits écrans OLED grâce à l'arduino UNO et un fichier tout prêt trouvé sur internet.

Ça me fait un peu peur de m'attaquer à un si gros projet, heureusement que je sais où demander de l'aide :oops:


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 5 invités