Il était une fois, je suis tombé sur l'interrupteur horaire numérique électronique VL-76-S, neuf, dans son emballage, mais dans un état défectueux. Aucun défaut n'a été trouvé sur les cartes de circuits imprimés à l'intérieur. Par conséquent, mariage d'usine, firmware cassé.
Vue générale du relais.Ce qui nous a surpris, c'est l'utilisation du microcontrôleur populaire et simple ATTiny2313. Extérieurement, cette conception se compose d'un maître sous la forme de trois décennies de commutateurs et d'une borne à laquelle l'alimentation 220 V et les contacts d'un relais EM sont connectés. La plage de la tâche est de 0,1 ... 99,9 minutes. par incréments de 0,1 min (6 secondes). Il n'y a pas de circuits et de firmware sur cette conception sur Internet, ce qui n'est pas surprenant. Sans réfléchir à deux fois, j'ai décidé de dessiner le circuit à partir des cartes de circuits imprimés et à l'avenir, j'écrirais moi-même le programme sur le MK.
La conception se compose de trois cartes de circuits imprimés interconnectées. Sur la première carte, un bloc d'alimentation et un relais d'exécution TRA3 sont réalisés. L'alimentation se fait selon un circuit sans transformateur: des condensateurs d'extinction sont utilisés pour réduire la tension. Sur la deuxième carte se trouve l'ATTiny2313 MK et d'autres éléments auxiliaires. Sur la troisième carte se trouvent des interrupteurs (points de consigne) et une LED de contrôle.
Photo de la troisième planche de dos.Je vais commencer la description avec le troisième tableau. Les commutateurs sont des commutateurs à 10 positions. Il n'y a aucun marquage dessus, chacun d'eux a 5 contacts. Par conséquent, selon la position, certains contacts sont fermés dans diverses combinaisons. Appelant des contacts, j'ai tout de suite saisi le schéma: une sortie fixe (générale) est fermée avec les quatre autres sorties (informations) selon la représentation binaire du nombre correspondant au numéro de la position sélectionnée. Par exemple, si la position «3» est sélectionnée, la sortie générale (cinquième consécutive) se ferme avec la sortie des troisième et quatrième, puisque le nombre «3» en représentation binaire est «0011». Voici un tel interrupteur délicat. Et il y en a trois. Ils sont connectés via des connecteurs XP1 et XP2 à la deuxième carte avec MK. Un connecteur XP3 connecte une LED et quelques autres conneries inutiles non soudées, pour lesquelles il y a une place sur la carte. Il s'agit très probablement d'un commutateur DPDT à six broches commun (tel qu'un carré, PB22E06 par exemple). Peut-être que la carte est universelle, mais elle n'est pas utilisée dans ce modèle particulier.

Photo de la deuxième carte (principale).Appelant les contacts des commutateurs, je n'ai pas tout de suite compris le principe de leur connexion aux ports MK. Sur la carte principale, 8 transistors SMD sont immédiatement évidents. Il a découvert plus tard que ces transistors sont utilisés comme paires de diodes avec une anode commune. Leurs bases vont aux ports MK, et les collecteurs et les émetteurs vont commuter les contacts. Puis ils m'ont expliqué que dans de tels cas, il y a des paires de diodes, elles sonnent comme des transistors, mais ce ne sont pas des transistors. Au total, nous avons 16 conducteurs laissant les paires de diodes sur la troisième carte. Les trois quarts d'entre eux (12 pièces) viennent aux contacts d'information des interrupteurs (trois à quatre), et 4 restent libres. Il est facile de deviner qu'ils sont théoriquement fournis pour le quatrième commutateur, qui n'est pas absent, car il n'y a pas du tout d'espace sur la carte. Néanmoins, afin de ne pas violer la logique du raisonnement, je mentionnerai ce quatrième interrupteur imaginaire. Les extrémités communes des deuxième et troisième, ainsi que les premier et quatrième commutateurs (mais le quatrième ne prévoit pas la carte) sont connectées ensemble par paires par des pistes dans la carte principale sur les connecteurs homologues XS1 et XS2. Ces deux paires sont connectées aux sorties des groupes de transistors. Ces deux groupes identiques sont réalisés sur les transistors BC857 et BC847 (structures différentes). Leurs entrées sont connectées au MK. Lors de l'application d'un "0" logique à l'entrée de ce groupe, la sortie sera également un "0" logique. De plus, sur la carte il y a un connecteur XP2 pour le firmware MK, connecté aux bornes SPI de l'interface MK, un connecteur XS3 pour une LED et un connecteur XP1 connecté par un câble à la première carte. Il convient de rappeler que certains des ports MK peuvent être utilisés à la fois pour SPI (pour le firmware) et pour les entrées-sorties ordinaires (fonctionnent dans le circuit).
Tout ce qui précède se reflète dans les diagrammes que j'ai dessinés d'abord dans le projet, puis dans SPlan. Les valeurs nominales des éléments radio non marqués (par exemple, les condensateurs CMS) sont absentes dans les diagrammes, elles ne sont pas si importantes. Tout d'abord, je vais donner un schéma de la carte principale et de la carte avec les setters (signatures des photos ci-dessous).
Schéma de la carte principale.Schéma de la troisième planche avec settersConsidérez comment l'interrogation de chaque setter. Les signaux des ports PB4 et PB5 MK logique "0" ouvrent les transistors VT2 et VT1, suivis de VT4 et VT3, se connectant aux contacts communs du bus zéro des commutateurs n ° 1 et n ° 2-n ° 3, respectivement. Cela se produit à son tour. Premièrement, le «0» logique provient de PB4 (PB5 a jusqu'à présent été réglé sur «1» logique), connectant les deuxième et troisième commutateurs. Dans cet état, les valeurs des signaux sont enregistrées tour à tour par le contrôleur à partir des ports d'entrée PB3, PB2, PB1, PB0 via les groupes de diodes 2VD1 ... 2VD4 à partir du deuxième et du quatrième commutateur manquant. Immédiatement, les valeurs des signaux des broches PD6, PD5, PD4, PD3 MK sont fixées, auxquelles les signaux des premier et troisième commutateurs passent par les groupes de diodes 2VD5 ... 2VD8. Mais, puisque seuls les deuxième et troisième commutateurs sont connectés par un contact commun, les signaux du deuxième commutateur parviendront aux premiers ports spécifiés du MK et le quatrième sera ignoré. De même, les signaux du troisième commutateur parviendront à la seconde moitié du MK et le premier sera ignoré. À ce stade, le contrôleur sait dans quelles positions les deuxième et troisième commutateurs sont installés. Après cela, PB4 est réglé sur «unité», désactivant les deuxième et troisième commutateurs, et PB5 est réglé sur «zéro». Dans ce cas, le premier et le quatrième interrupteurs manquants sont connectés par une extrémité commune au «boîtier». Leur interrogation se produit exactement de la même manière que dans le cas précédent, mais maintenant les signaux de ces commutateurs qui ont été ignorés la dernière fois seront enregistrés. Ainsi, le contrôleur connaît les informations de position de tous les commutateurs. Ce processus est similaire à l'interrogation d'un clavier matriciel, mais dans ce cas, une matrice à 4 couches avec des dimensions de 2 par 2 avec un élément manquant.
Résistances R8 ... R15 - tractions. Cependant, il était possible de "tirer vers le haut" dans le MK lui-même. La fréquence d'horloge précise MK fournit du quartz à 10 MHz. Circuit de réinitialisation R1 et C4 - MK. Il n'y a rien de plus intéressant sur ce forum.
Photo de la première carte (d'alimentation) du côté des éléments.
Photo de la première carte (d'alimentation) de l'arrière.Passons au schéma de la première planche (Fig. Ci-dessus). Le schéma semblait très intéressant et à certains endroits incompréhensible.
Schéma de la première carte (d'alimentation).C1C2 - pour réduire la tension. R1 - pour décharger ce qui précède. Après le pont de diodes DB1 se trouvent deux électrolytes. Pour compliquer le circuit (ou pour la fiabilité) - schéma de stabilisation en cascade VT3R6VD3 - VT7R12VD5. Le VD5 est similaire à un transistor SMD à émetteur non utilisé. Cela fournit une tension continue stabilisée de 12V. Ensuite, le régulateur linéaire VR1 à 5V. Dans le même temps, la tension est supprimée du pont de diodes DB1 à travers la diode VD2 vers un autre stabilisateur 24 V VT1R3VD1. Cette tension est fournie à la bobine du relais EM Rel1 et à R17. Ce dernier ne sait pas pourquoi. À l'autre extrémité de R17 vient le signal du groupe de transistors VT9VT10. Le circuit de ce groupe est similaire au circuit de la carte principale. Un signal provenant d'un port MK PB6 séparé arrive à l'entrée de ce groupe de transistors via le connecteur. Pourquoi est-il nécessaire? Pourquoi connecter une résistance R17 à 24V? Très probablement, il y avait une idée qu'au lieu d'une résistance, vous pouvez mettre autre chose, par exemple, une LED de contrôle interne, en programmant le port PB6 MK d'une certaine manière. Ou un nœud de commutation supplémentaire. Mais, tout de même, c'est un non-sens, comme l'ont dit mes connaissances des ingénieurs radio, après avoir examiné le tableau de conception. La deuxième extrémité du relais EM Rel1 est connectée à un groupe de transistors similaire VT2VT5, et elle est connectée au port MK PD0. Le signal "0" de ce port active le relais EM en cours d'exécution. La chose la plus intéressante est que la LED externe est connectée non pas parallèlement au relais EM, mais à l'espace de l'émetteur du transistor VT2, en outre, via deux connecteurs (passant la carte principale). Sur le terminal, les broches 1 et 2, à en juger par l'autocollant sur le relais, restent vides. Mais dans le circuit, le contact n ° 2 est connecté à un fil commun, et le contact n ° 1 est alimenté à l'entrée du groupe de transistors VT6VT8. La sortie de ce groupe est envoyée au port PD2 MK. Plus tard, j'ai lu dans les spécifications de ce modèle de relais que ces contacts sont utilisés pour contrôler d'autres modèles de relais, assemblés dans le même boîtier. Le modèle que j'envisage n'implique pas de contrôle, mais il peut être implémenté lors de l'écriture d'un programme sur MK, car le schéma offre cette possibilité. Sous le contrôle peut signifier un démarrage, une réinitialisation (à la fois en «déclencheur» et en mode normal), et tout ce qui vous vient à l'esprit. Les spécifications des autres relais présentent des chronogrammes qui montrent le comportement des relais en fonction d'un signal de commande donné. Il est également indiqué ci-dessous: à la demande du client, nous pouvons mettre en œuvre tout schéma possible. Et le dernier moment du schéma. Ce signal de commande de la borne n ° 1 vient également du transistor VT4 inutile, alimenté par une tension de 12V. C'est là encore une complication du schéma. Ou peut-être y a-t-il encore une idée posée? Je n'ai pas fouillé profondément. Je serai heureux de tout commentaire.
Les marquages des bornes des connecteurs sont signés par le point après le nom du connecteur lui-même. Les chiffres romains après le symbole «~» indiquent des conclusions inutiles et manquantes. Ces derniers ne sont pas rares dans le schéma, mais je ne m'attarderai pas sur eux. Ci-dessous, je donne des croquis de chaque carte avec les désignations des connecteurs, les conclusions et les éléments de base.
Croquis du tableau.Considérez la description du code source du programme MK. Le programme lui-même est simple et a été écrit par moi dans CVAVR pendant 20 minutes. Je vais discuter de l'algorithme par lequel le programme sera exécuté. Ces informations peuvent sembler assez banales pour certains, mais elles ne seront pas superflues pour les débutants. Dans ma version de l'algorithme, les temporisateurs du relais temporel seront interrogés non pas une fois, mais en continu. De plus, l'interrogation continuera même après le déclenchement du relais. Cela vous permettra de faire des ajustements lors de vos déplacements. Peut-être que cet algorithme ne coïncide pas avec l'algorithme d'origine pour le fonctionnement de ce relais, mais je ne connais pas l'algorithme d'origine. C'est sur l'exemple de l'algorithme précité que la description du programme sera considérée.
Code source du programme C avec description.Nous connectons la bibliothèque pour travailler avec l'ATTiny2313 MK, ainsi que la bibliothèque des fonctions de retard.
#include <tiny2313.h> #include <delay.h>
Ensuite, nous faisons la macro substitution nécessaire, en fonction des affectations de circuit des ports MK. Ces substitutions sont pratiques car dans le texte du programme au lieu, par exemple, de PORTB.5, vous pouvez écrire getAD, ce qui est plus pratique. La compilation getAD sera interprétée comme PORTB.5. Ainsi, la première substitution est les sorties pour connecter les premier (A) et quatrième (D) commutateurs de consigne. Le second est pour le deuxième (B) et le troisième (C). Vient ensuite la substitution pour activer le relais. Et enfin, la substitution «Ctrl» qui n'est pas utilisée dans le programme et dans le modèle considéré. Vous ne pouvez pas l'écrire.
#define getAD PORTB.5 #define getBC PORTB.4 #define RL PORTD.0 #define Ctrl PIND.2
Les variables A, B, C sont utilisées pour stocker le numéro de position des trois commutateurs correspondants et prendre des valeurs de 0 à 9.
unsigned char A,B,C;
Variable i - la valeur actuelle du nombre du dixième de minute (6 secondes), c'est-à-dire le numéro du «tick» minimum du relais. La variable t est le nombre de dixièmes de minute (ticks) reçus du maître.
unsigned int i=0,t;
La fonction principale du programme est présentée ci-dessous. Dans les 6 premières lignes, je n'ai pas compris. Ils sont formés à l'aide de l'utilitaire auxiliaire CodeWizadAVR et sont associés à la présence de quartz externe à 10 MHz.
void main(void) { #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif
Les deux lignes suivantes configurent le port B de notre MK. Selon le schéma, nous mettons les 4 bits inférieurs à l'entrée et les plus importants à la sortie (PB7 n'est pas utilisé et PB6 est inutile, mais, en théorie, la sortie). Par conséquent, selon les principes de configuration MK, que je ne décrirai pas, nous écrivons le nombre 240 dans le registre DDRB (F0 en notation hexadécimale). Le niveau de sortie initial est «1», à l'exception du PB7 inutile. Et juste au cas où, connectons les «résistances de pull-up» de MK aux entrées, même si elles sont déjà installées dans le circuit. Pour ce faire, définissons le registre PORTB sur 7F en notation hexadécimale.
PORTB=0x7F; DDRB=0xF0;
Le port D est configuré de la même manière. Toutes les broches de l'entrée, à l'exception des deux inférieures. Les «résistances de rappel» à l'entrée et le niveau de sortie initial «1» à la sortie sont similaires.
PORTD=0x7D; DDRD=0x03;
Les cinq lignes suivantes concernent la configuration de l'un des minuteurs MK. Cette minuterie est à seize chiffres, c'est-à-dire qu'elle fournit un score allant jusqu'à 2 ^ 16 = 65536. La fréquence de comptage est déterminée par la fréquence d'horloge MK et le coefficient de division (l'un des cinq prédéfinis). Dans le programme décrit, il a été décidé de garder un compte pendant 6 secondes (étape de tâche minimale), puis d'augmenter la variable i de 1 et de réinitialiser la minuterie au début du comptage. Pour garantir ce qui précède, vous devez prendre le rapport de division maximum de 1024 et compter jusqu'à 58594. Ce dernier est facile à calculer. Fréquence MK - 10 000 000 Hz. En utilisant un rapport de division de 1024, la fréquence de la minuterie sera de 10 000 000/1 024 = 9 765,625 Hz et la période sera de 1 024 000/10 000 000 = 0,0001024 s. Dans les 6 secondes, 6 / 0,0001024 = 58593,75 de ces périodes seront empilées. Ce nombre se trouve dans le temporisateur 16 bits, mais ce n'est pas un entier, vous devez donc arrondir à 58594. Dans ce cas, l'erreur de notre relais temporel sera insignifiante: 58594-58593,75 = 0,25; 0,25 * 0,0001024 = 0,0000256; 0,0000256 * 999 = 0,0255744. Autrement dit, pour la période de temps maximale possible (99,9 minutes), l'inexactitude de ce relais temporel sera d'environ 25,6 millisecondes, ce qui est tout à fait acceptable dans la pratique. Soit dit en passant, le fabricant stipule également l'erreur de l'appareil, et notre erreur ne sera pas pire. Dans le registre de configuration du temporisateur TCCR1B, écrivez la valeur 5. Sans entrer dans les détails, cela signifie que le temporisateur démarre et que le coefficient de division est 1024. Dans le registre TCNT1, nous écrivons la valeur 0. Ce registre est de 16 bits et est divisé en deux moitiés de 8 bits: le plus jeune (L ) et senior (H). La valeur y est écrite, d'où la minuterie continuera de compter. Nous devons compter à partir de zéro. La valeur OCR1A s'enregistre avant laquelle le temporisateur lira, après quoi il appellera la fonction d'interruption. À ce moment, la fonction principale du programme est interrompue et les actions spécifiées dans la fonction de cette interruption sont exécutées. Après avoir pratiqué l'interruption, la fonction principale continuera de s'exécuter. Cette valeur, comme cela a été dit ci-dessus, est égale à 58594 (E4E2 en notation hexadécimale). Étant donné que le registre OCR1A est également divisé en deux moitiés, nous écrivons la valeur ci-dessus en parties.
TCCR1B=0x05; TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0xE4; OCR1AL=0xE2;
Les deux lignes suivantes configurent correctement la résolution des interruptions (n'entrez pas dans les détails).
TIMSK=0x40; #asm("sei")
Dans le cycle principal, les commutateurs de réglage sont constamment interrogés (selon l'algorithme dans la description du circuit) en utilisant des retards de 30 ms pour un fonctionnement correct et stable. En définissant la valeur «0» sur PORTB.5 (getAD = 0), nous préparons le premier commutateur. Ses conclusions sont connectées au port D du MK aux broches 6, 5, 4, 3. La direction va du plus jeune au plus ancien. C'est-à-dire que le bit de poids faible du commutateur est connecté au bit de poids faible (bit 3) du port MK. Par conséquent, afin de recevoir des informations du port D du MK sur la position du premier commutateur, il est nécessaire de faire un décalage au niveau du bit vers la droite de trois positions (PIND >> 3), inverser les bits reçus avec l'opération "~" (puisque les informations viendront en "0", selon le schéma) et réinitialiser les quatre bits supérieurs inutiles de la valeur de 8 bits reçue. La dernière opération se fait par multiplication logique au niveau du bit du résultat par le nombre 15 (00001111 en représentation binaire). Après cette opération, la variable A se verra attribuer la valeur de position du premier interrupteur. Ensuite, le premier interrupteur est désactivé et les deuxième et troisième sont préparés. La valeur du deuxième commutateur à la variable B est prise du port B du MK de la même manière, mais sans opération de décalage, car les bornes de ce commutateur sont connectées aux broches les plus basses du port B du MK et également de manière co-directionnelle. Les informations du troisième commutateur vers la variable C sont supprimées de la même manière que le premier. Après cela, les deuxième et troisième commutateurs (getBC = 1) sont «fermés» et la valeur définie (le nombre de dixièmes de minute) des trois commutateurs est calculée dans la variable t.
while(1){ delay_ms(30); getAD=0; delay_ms(30); A=(~(PIND>>3)&15); delay_ms(30); getAD=1; getBC=0; delay_ms(30); B=(~PINB)&15; C=(~(PIND>>3)&15); delay_ms(30); getBC=1; t=100*A+10*B+C; } }
La comparaison de cette variable et d'une variable en temps réel similaire i se produit dans la fonction d'interruption.
interrupt [TIM1_COMPA] void timer1_compa_isr(void){ i+=1; if(i>=t){ RL=0; }else{ RL=1; } TCNT1H=0x00; TCNT1L=0x00; }
Si la dernière variable dépasse la valeur définie, le «relais d'exécution» (RL = 0) s'allume de «0». De plus, il s'éteindra si, en même temps, les commutateurs sont réglés sur une valeur supérieure à celle qui a fonctionné dans la variable i. Dans la même fonction d'interruption, la variable i est augmentée de 1 et le temporisateur est remis à 0.
Les bits FUSE ont été radiés de MK et sont restés inchangés. Je les ai analysés, tout va bien là-bas.

Ainsi, non seulement le schéma de l'appareil a été copié, mais également un programme MK a été développé, qui ne diffère pas en fonctionnalités de celui propriétaire. De plus, il est devenu possible au niveau logiciel de modifier de manière assez flexible (et surtout, gratuite) les paramètres de temps de l'appareil et d'utiliser la sortie de contrôle (n ° 1 sur le terminal) dans diverses fonctionnalités. Le programme est si simple qu'il peut (encore mieux) être écrit en assembleur, mais je ne le fais pas encore.