Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Automation Discussion :

Gestion d'un DB dans TIA Portal


Sujet :

Automation

  1. #1
    Futur Membre du Club
    Gestion d'un DB dans TIA Portal
    Bonjour,
    Je travaille sur TIA Portal V14 et un S7 1200.
    Je développe des blocs fonctions pour mon boulot. Au niveau du bloc et des variables pas de soucis pour réintégrer dans d'autres programmes par contre j'ai un souci avec mon DB. Dans mon programme initial j'avais un DB3 que j'utilisais en bloc non optimisé ( pas le choix, j'ai un tableau d'octet et je dois manipuler des octets, des mots et double mots). Dans mes blocs j'ai donc des adresses type %DB3.DBW0. Problème, si j'intègre la fonction dans un programme qui a déjà, par exemple, 5 DB, mon bloc fonction s’exécute avec un DB6 donc ça ne fonctionne plus.
    J'ai bien essayé de trouver quelque chose qui me permettent d'aller lire le numéro du DB en faisant %DBn.DBW0 puis mettre le numéro de DB lu dans n mais impossible.

    Je travaille avec les bibliothèques IO Link, je dois manipuler les données par l'intermédiaire de ces DB; je ne pense pas pouvoir m'en passer malheureusement.
    Quelqu'un aurait il une idée ?

    Merci d'avance.

  2. #2
    Nouveau membre du Club
    Bonjour,
    Je suis désolé mais j'ai mal à comprendre ce que tu cherches à faire. Essaye de regarder du côté des instructions PEEK et POKE en SCL ça devrait résoudre ton problème.

  3. #3
    Futur Membre du Club
    DB IO Link
    Bonjour Sidonay,

    D'abord merci d'avoir lu mon message.
    Avec mon bloc IO Link je crée un DB sur lequel est attribué un numéro (ce sont les données à envoyer à mon esclave IO Link via la bibliothèque Siemens). Lorsque je crée mon bloc fonction, ce numéro est repris (si je crée mes données IO Link en DB3, ça reste en DB3 dans mon bloc fonction).
    Le problème est que le client va aussi créer un DB pour sa bibliothèque IO Link mais ce DB ne sera pas forcément en 3 et mon bloc fonction ne va pas faire référence à son DB à lui donc il ne fonctionnera pas. En fait je ne sais pas si je suis beaucoup plus clair.

    Sur mes bibliothèques OMRON, je crée par exemple 2 variables EIP_INPUT, EIP_OUTPUT sur mon bloc fonction et le client renseigne ces 2 champs avec ses variables et ça roule. C'est de l'Ethernet IP c'est moins lourd à gérer que les requêtes IO Link mais dans le principe c'est ce que je voudrais faire avec mon Siemens sur le DB des données. Problème, les DB ne sont pas des variables et lorsque j'intègre ma fonction, mon DB de données s'intègre dans le programme utilisateur avec le numéro initialement défini.

    J'espère que c'est un poil plus clair. L'utilisation des Peek et Poke semble une bonne idée mais je ne suis pas sûr d'avoir le niveau pour manipuler ça correctement. Je vais explorer cette piste quand même. Si vraiment tu es motivé je pourrais t'envoyer mon programme (TIA Portal V14)

    Merci d'avance :-)

    Pascal.

  4. #4
    Membre actif
    Salut

    Sous S7-300 tu aurais pu utiliser la fonction "WORD_TO_BLOCK_DB"
    ici tu dois passer par "POKE" et PEEK
    Par contre je ne vois pas pourquoi tu veux garder une db non optimisé,
    tu ne pourrais pas plutôt faire un UDT et dans ton FB mettre cet UDT en InOut ?

  5. #5
    Futur Membre du Club
    DB IOLINK
    Salut Madpo,

    Merci pour ta réponse.
    Le problème est que dans la fonction IOL CALL de Siemens pour la com IO Link le format des données est un tableau de 232 octets. On a pas le choix. Comme je pilote un contrôleur d'axe, j'ai des octets, des mots et des double mots à utiliser dans mes requêtes IO Link. Mon bloc non optimisé est le seul moyen que j'ai trouvé pour remplir le tableau avec autre chose que des octets (DBB, DBW et DBD, dans un programme ça tourne tranquille), je crains de me retrouver avec des incompatibilités de type avec un UDT. Cela dit je n'ai pas cherché de fonction permettant convertir un mot ou un double mot en octet. je viens d'y penser en rédigeant ce post. ça existe sur Sysmac, RS Logix et Unity ça m'étonnerais que ça n'existe pas sur le TIA.

    je vais quand même creuser les peek et poke, je dois revenir à mon premier amour, un ZX Spectrum +, :-)

    Pascal.

  6. #6
    Nouveau membre du Club
    Bonjour Pascalkimi,
    Désolé de répondre aussi tard, j'aurais du temps je pourrais éventuellement réfléchir à la question de te le faire, mais tu es payé pour faire ça alors à toi de joué . Il y'a 2 solutions, mais tu es obligé de passer par des instructions avancé, il y'aurait bien une 3éme mais je ne crois pas qu'elle soit adapté à ton cas.
    Ma réponse arrive peut être trop tard mais au pire cela servira à d'autre.

    la première reste effectivement le Peek et le Poke elles sont conçu pour travailler avec des DB non optimisé.
    la 2éme consiste à utiliser les constantes système générer lors de l'ajout de matériel dans la config.
    la 3éme est d'utilisé les MOVE_BLK_VARIANT

    Solution 1 :
    voici une illustration d'un peek pour aller lire sur une zone mémoire indexé (à adapter selon ton besoin, ici on lit des bits):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    
    (* Déclaration des variables *)
    	Input			
    	Array_of_bool	Variant		Tableau de bit
    	DB_Num	Int		Numéro de DB scruté
    	ByteStart	Int		
    
    	Output			
    	Error	Bool		Actif si présence d'une erreur
    	Num_Bool	Int		Numéro de bit actif
    	Size	UDInt		Taille du tableau scruté
    
    	InOut			
    				
    	Temp			
    	N_Bool	UDInt		
    	Count	DInt		
    	Count2	Int		
    	Result	Bool		
    
    	Constant			
    	Type	Byte	16#84	Type de zone mémoire à lire, ici c'est un DB
    (* fin déclaration variable *)
    
    #Num_Bool := 0;
    
    IF TypeOfElements(VAR:=#Array_of_bool)=TypeOf(OPERAND:=#Result) AND IS_ARRAY(OPERAND := #Array_of_bool) THEN
        #N_Bool := CountOfElements(IN := #Array_of_bool);
        #N_Bool := #N_Bool;
        #Size := #N_Bool;
    ELSE
        ENO := false;
        RETURN;
    END_IF;
    
    FOR #Count := #ByteStart TO UDINT_TO_INT((#N_Bool)/8)+#ByteStart DO
        FOR #Count2 := 0 TO 7 DO
            #Result := PEEK_BOOL(area := #Type, dbNumber := #DB_Num, byteOffset := #Count, bitOffset := #Count2);
            
            IF #Result = true THEN
                #Num_Bool := (#Count-#ByteStart)*8+#Count2;
                ENO := true;
                RETURN;
            END_IF;
        END_FOR;
        
    END_FOR;
    
    ENO := false;
    Voici le poke (c'est un simulateur d'entrée), toujours pareil a adapter ici on écrit des bits.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    (* Déclaration variables *)
    	Input		
    	N_DB	Any			Numéro de DB à affecter
    
    	Input_1 [AT "N_DB"]	Struct			
    	Init	Byte			Propre à l'API
    	Type	Byte			Type de données
    	Repeat	Int			Longueur zone
    	N_DB	Int			Numéros de DB
    	Area	Byte			Zone mémoire
    	Address 1	Byte			Adresse octet
    	Address 2	Byte			Adresse octet
    	Address 3	Byte			Adresse octet
    
    	Sim_code	Byte			Valeur en hexadecimal des entrées à simuler
    	Word_in	Byte			Word d'entrées
    	Flip_code	Byte			Valeur en hexadecimal des entrées à inverser
    		
    	Output				
    					
    	InOut				
    					
    	Temp				
    	Count	Int	0.0		
    	LoadNumArea_In	Int	2.0		Numéro d'octet
    	Copy_sim	Byte	4.0		
    	Map_sim	Array[0..7] of Bool	4.0		
    	Result_In	Byte	5.0		
    	Map_result	Array[0..7] of Bool	5.0	
    	
    	Constant				
    					
    (* Fin déclaration *)
    
    (*Initialisation*)
    
    #LoadNumArea_In.%X15 := #Input_1."Address 1".%X2;
    #LoadNumArea_In.%X14 := #Input_1."Address 1".%X1;
    #LoadNumArea_In.%X13 := #Input_1."Address 1".%X0;
    
    #LoadNumArea_In.%X12 := #Input_1."Address 2".%X7;
    #LoadNumArea_In.%X11 := #Input_1."Address 2".%X6;
    #LoadNumArea_In.%X10 := #Input_1."Address 2".%X5;
    #LoadNumArea_In.%X9 := #Input_1."Address 2".%X4;
    #LoadNumArea_In.%X8 := #Input_1."Address 2".%X3;
    #LoadNumArea_In.%X7 := #Input_1."Address 2".%X2;
    #LoadNumArea_In.%X6 := #Input_1."Address 2".%X1;
    #LoadNumArea_In.%X5 := #Input_1."Address 2".%X0;
    
    #LoadNumArea_In.%X4 := #Input_1."Address 3".%X7;
    #LoadNumArea_In.%X3 := #Input_1."Address 3".%X6;
    #LoadNumArea_In.%X2 := #Input_1."Address 3".%X5;
    #LoadNumArea_In.%X1 := #Input_1."Address 3".%X4;
    #LoadNumArea_In.%X0 := #Input_1."Address 3".%X3;
    
    #Copy_sim := #Sim_code;
    
    (*--------------------------------
    Execution 
    --------------------------------*)
    
    #Result_In :=#Word_in XOR #Flip_code;
    
    FOR #Count:= 0 TO 7 DO
        
        //Contrôle si entrée en simulation
        IF #Map_sim[#Count]=false THEN
            
            POKE_BOOL(area := #Input_1.Area,
                      dbNumber := #Input_1.N_DB,
                      byteOffset := #LoadNumArea_In,
                      bitOffset := #Count,
                      value := #Map_result[#Count]);
            
        END_IF;
    
    END_FOR;
    
    ENO := true;
    Solution 2 :
    Utilisations constante système, dans le menu Variables d'api tu as un onglet constante système, c'est ici que l'on retrouve tout les accès à la périphérie il faut donc retrouver la variable généré par ton équipement :
    je prend l'exemple d'un robot kuka chez moi sa donne ça :



    à ton bloc tu inséres une entrée de type HW_SUBMODULE à laquelle tu affecteras ta constante. A l'intérieur du bloc tu inséres ce morceaux de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    (* Déclaration variables *)
    INPUT
    	Add	HW_SUBMODULE	0.0	0	Identification des entrées/sorties
    
    TEMP 
    	HWModule	Struct	0.0							
    	Nbr_In	UDInt	0.0							
    	Size_In	UInt	4.0							
    	Nbr_Out	UDInt	6.0							
    	Size_Out	UInt	10.0							
    	Ret_val	Int	12.0							
    
    (* fin déclaration *)
    
    #HWModule.Ret_val := RD_ADDR(LADDR := #Add, PIADDR => #HWModule.Nbr_In, PICount => #HWModule.Size_In, PQADDR => #HWModule.Nbr_Out, PQCount => #HWModule.Size_Out);
    
    //Lectures des entrées
    LECTURE DES ADRESSES
        FOR #Count := 0 TO UINT_TO_INT(#HWModule.Size_In) - 1 DO
            #Buffer[#Count] := PEEK(area := 16#81, dbNumber := 0, byteOffset := UDINT_TO_INT(#HWModule.Nbr_In) + #Count);
        END_FOR;
    
    //Ecriture des sorties
        FOR #Count := 0 TO UINT_TO_INT(#HWModule.Size_Out) - 1 DO
            POKE(area := 16#82,
                 dbNumber := 0,
                 byteOffset := UDINT_TO_INT(#HWModule.Nbr_Out) + #Count,
                 value := #Buffer[#Count]);
        END_FOR;

  7. #7
    Futur Membre du Club
    Utilisation DB
    Bonjour Sidonay,

    Merci pour ta réponse.
    En fait c'est toujours d'actualité puisque j'avais renoncé à faire des librairies en IO Link sur Siemens pour nos contrôleurs. Celle de Siemens est très bien comme ça. Je me suis contenté d'une fonction pour les données de process. Sur Omron c'est bien plus simple.
    En ce qui concerne ton code, force est de reconnaitre que je suis loin d'avoir ton niveau mais ça vaut le coup de regarder ne serait ce que par respect pour le temps que tu y as consacré.
    Je vais donc analyser ça avec beaucoup d'attention et vu le temps qu'on va passer en confinement je vais pouvoir me pencher dessus tranquille surtout que j'ai mon Siemens avec moi ;-)

    Encore merci.

    Pascal.

###raw>template_hook.ano_emploi###