Se connecter
Se connecter

ou
Créer un compte

ou
FR
EN

Le pub des programmeurs

  • 1 927 réponses
  • 117 participants
  • 131 692 vues
  • 130 followers
Sujet de la discussion Le pub des programmeurs
Salut :coucou: y a des programeurs sur AF si oui vous bossez sous quoi ?
Afficher le sujet de la discussion
1851
yes !

Chris Kazvon

-------------------------------------------------

Introduction à Hornresp et Tutoriels  -  Tutoriels Vidéo pour Room EQ Wizard

1852
Et aussi avant le disque dur ?
1853
je referai la vérif mais oui :)

je pense que j'ai pas dû prendre les bons / assez de fichiers

du coup je vais tester avec Ubuntu, y a qu'un seul fichier à télécharger, on peut pas se tromper !
je vous tiens au jus :)

Chris Kazvon

-------------------------------------------------

Introduction à Hornresp et Tutoriels  -  Tutoriels Vidéo pour Room EQ Wizard

1854
Et désactiver le secure boot, qui est souvent mis par défaut dans les BIOS UEFI/récents.

« What is full of redundancy or formula is predictably boring. What is free of all structure or discipline is randomly boring. In between lies art. » (Wendy Carlos)

1855
Je suis en train de faire du C pour stm32 en ce moment (de l'embarqué donc) et je galère avec un truc tout simple. Sur ma carte (une nucleo F303RE) il y a un bouton. Et j'aimerais que ce bouton déclenche une interruption quand il est pressé et lâché et afficher le résultat sur le port série. jusque la rien de sorcier voici mon code :

Voici la boucle principale de l'application :
main.c

 while (1)
  {
    /* USER CODE END WHILE */
      if (toto && HAL_GPIO_ReadPin(B1_Pin, B1_GPIO_Port))
      {
          HAL_UART_Transmit(&huart2, "B=1\r\n", 6, 10);
      }
      if (toto && !HAL_GPIO_ReadPin(B1_Pin, B1_GPIO_Port))
      {
          HAL_UART_Transmit(&huart2, "B=0\r\n", 6, 10);
      }
      toto = 0;
    /* USER CODE BEGIN 3 */
  }/


Voici la configuration de l'interruption :
main.c

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
 [...]

  /*Configure GPIO pin Output Level */
 [...]
  /*Configure GPIO pin : B1_Pin */
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; //Interruption sur front montant (on) et descendant (off)
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : LD2_Pin */
  [...]

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

}


stm32f3xx_it.c
void EXTI15_10_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */
  toto = 1;
  /* USER CODE END EXTI15_10_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */

  /* USER CODE END EXTI15_10_IRQn 1 */
}


La variable toto est de type char et est définie dans le fichier main.h qui est inclus dans main.c mais aussi dans stm32f3xx_it.c

J'ai paramétré le type de detection sur front montant et descendent via la ligne
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;


Le code tel quel fonctionne à peu près. C'est à dire que quand je presse le bouton, j'ai sur mon terminal "B=1" mais quand je le relache... aussi. Je ne comprends pas pourquoi... Quelqu'un a une idée ?
J'ai essayé avec HAL_GPIO_ReadPin(B1_Pin, B1_GPIO_Port) == 1 et HAL_GPIO_ReadPin(B1_Pin, B1_GPIO_Port) == 0 mais j'ai le même résultat.

[ Dernière édition du message le 13/01/2020 à 21:29:17 ]

1856
Et si tu mets le déclenchement juste sur ce qui correspond au relâchement du bouton ?

D’ailleurs généralement sur les IHM c’est fait comme ça : il ne se passe rien quand on enfonce le bouton de la souris, c’est quand on le relâche que l’action est effectuée.


Citation :
J'ai paramétré le type de detection sur front montant et descendent via la ligne
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

Le code tel quel fonctionne à peu près. C'est à dire que quand je presse le bouton, j'ai sur mon terminal "B=1" mais quand je le relache... aussi. Je ne comprends pas pourquoi... Quelqu'un a une idée ?

En fait je ne comprends pas le problème ; soit parce-que je ne comprends pas ce que tu veux obtenir, soit parce-que je ne comprends pas ce que tu obtiens.

[ Dernière édition du message le 13/01/2020 à 21:36:56 ]

1857
Non j'ai besoin d'avoir l'information de quand le bouton est appuyé et de quand il est relaché, il y aura des traitement différents pour les deux cas. Par exemple dans le cas d'un clavier midi si tu presse une note, un message midi est envoyé. Quand tu la relâche c'est un autre message midi, différent, qui est envoyé.

Dans mon cas je shouaite que le message "B=1" soit envoyé sur le port série quand je presse le bouton et le message "B=0" quand je le relache.

[ Dernière édition du message le 13/01/2020 à 21:44:50 ]

1858
1859
edit
Citation :
GPIO_InitStruct.Pull = GPIO_NOPULL;


t'es sur que tu ne veux pas la pullup ? j'esperes que tu as une résistance en externe.

tu devrais laissé l'interuption modifier toto et lire le resultat dans la while loop et l'envoyer sur le port série.

méfie toi également l'interuption ne fait pas le distinguo entre rising et falling, c'est a toi de la faire lors de l'interruption (lire les registers de GPIO)

mais en générale un button sur un inter risque d'etre problématique a cause du rebond des contacts internes au switch. Il te faut une solution debounce.

rumorofsmoke.github.io/

[ Dernière édition du message le 13/01/2020 à 22:43:57 ]

1860
1861
une methode qui marche super bien je trouve c'est le debounce qu'on trouve sur les modules mutable instruments. une loop a 1Khz et un ring buffer traité dans la while loop.

rumorofsmoke.github.io/

1862
Pouet > Non dans l'appliction finale, le cpu fera autre chose durant ce laps de temps (la je cherche juste à valider l'idée)

redpill > Merci pour l'idée du debounce ! Je n'y avais pas pensé en effet ca va m'être utile. J'avais essayé de basculer le tout dans la fonction d'interruption, mais ca ne fonctionnais pas mieux.
1863
essayes peut etre plutot un truc comme ca.
toto = 0; 

main()
{
pin_setup(bouton); 
interuption_setup(#pin)

while(
    new_toto = toto;     //fais le code uniquement si toto a changé
    if(new_toto != old_toto)
    {
         send_to_UART(toto);
        old_toto = new_toto;     //pour éviter l'envoi continuel
    }
    
}

interuption_pin{
    clean_inter; //important !!
    if(PIN == 0) toto = 0;  //lis l'état de la pin
    else toto = 1; 
}

rumorofsmoke.github.io/

[ Dernière édition du message le 13/01/2020 à 23:03:24 ]

1864
Citation de Patrick :

J'ai paramétré le type de detection sur front montant et descendant

Le code tel quel fonctionne à peu près. C'est à dire que quand je presse le bouton, j'ai sur mon terminal "B=1" mais quand je le relache... aussi. Je ne comprends pas pourquoi... Quelqu'un a une idée ?

Si tu n'as besoin de l'interruption que sur un seul front (montant ou descendant), pourquoi diable configurer l'EXTI pour faire péter une interruption sur les deux fronts?
Sinon, +1 pour le debounce aussi, quoiqu'il faudrait avoir le schéma de la connexion du bouton à la GPIO pour savoir si c'est vraiment nécessaire.

Resistance is not futile... it's voltage divided by current

1865
Citation de aaB :
Citation de Patrick :

J'ai paramétré le type de detection sur front montant et descendant

Le code tel quel fonctionne à peu près. C'est à dire que quand je presse le bouton, j'ai sur mon terminal "B=1" mais quand je le relache... aussi. Je ne comprends pas pourquoi... Quelqu'un a une idée ?

Si tu n'as besoin de l'interruption que sur un seul front (montant ou descendant), pourquoi diable configurer l'EXTI pour faire péter une interruption sur les deux fronts?
Sinon, +1 pour le debounce aussi, quoiqu'il faudrait avoir le schéma de la connexion du bouton à la GPIO pour savoir si c'est vraiment nécessaire.

C'est clair, je comprends pas pourquoi tu es etonne d'avoir les 2 quand tu demandes a avoir les deux ?
1866
aaB > non je voudrais avoir une interruption lorsque le bouton est appuyé puis quand il est relâché, pour faire des traitements diffèrents dans les deux cas. Pour ça j'ai essayé de checker l'interruption ET la valeur du bouton mais ça ne fonctionne pas (ça me renvoie toujours le même résultat c'est ce que je décris dans mon premier message)

Miles > ce qui m'étonne c'est d'avoir la même valeur alors que je m'attends dans le premier cas (bouton appuyé) je m'attends a recevoir B=1 et dans le second (bouton relâché) B=0 mais c'est peut être un problème de debouncing
1867
Dans ton code, tu initialises toto à 1, mais je ne vois nulle part de code qui modifie cette valeur.
La manière habituelle pour ce genre de truc, c'est d'aller lire l'état de la pin dans le registre de la GPIO pour déterminer si ton interruption a pété sur un front montant ou descendant.
Il devrait y avoir quelque part une ligne de code qui assigne à toto la valeur du bit adéquat dans le registre d'état de la GPIO.

Resistance is not futile... it's voltage divided by current

1868
un truc qui n'engage que moi, tu devrais peut etre coder sans les librairies tiers genre HAL, cubeX et compagnie. Tu comprendrais bien mieux ce que tu fais et ce qui se passe. C'est pas plus compliqué, c'est bien plus formateur et la methode est ensuite transposable a tout les micros que tu vas utilisé.

rumorofsmoke.github.io/

1869
Citation de aaB :
Dans ton code, tu initialises toto à 1, mais je ne vois nulle part de code qui modifie cette valeur.
La manière habituelle pour ce genre de truc, c'est d'aller lire l'état de la pin dans le registre de la GPIO pour déterminer si ton interruption a pété sur un front montant ou descendant.

C'est ce qui a l'air d'etre fait, le toto n'est utilise que pour transmettre la valeur une fois et la pin est lue pour verifier.

if (toto && !HAL_GPIO_ReadPin(B1_Pin, B1_GPIO_Port))
{
  HAL_UART_Transmit(&huart2, "B=0\r\n", 6, 10);
}
toto = 0;

[ Dernière édition du message le 14/01/2020 à 17:37:54 ]

1870
Vu que HAL_GPIO_ReadPin retourne un enum, je comparerai directement a l'enum pour etre sur de ce que je fais. On ne sait jamais.
1871
Dans ce cas, pourquoi ne pas faire le test et l'assignation directement dans la routine plutôt que dans la main loop?
On se retrouve avec un "micro driver" qui, sur interruption, mémorise l'état de la pin et lève un flag pour indiquer au reste du programme que l'état de la pin a changé.
Le programme traite le changement d'état et baisse le flag.

Resistance is not futile... it's voltage divided by current

1872
Question à propos de SQL:

Je veux faire un truc truc style rézosocio.

J'ai une table accounts pour les comptes.

J'ai ensuite pensé à créer une table relationship pour mes accounts.

Après maintes recherche j'ai pu comprendre qu'il était préférable de créer également la relation inverse.
Et je me suis dit qu'il était préférable d'avoir toutes les infos de la relation (depuis quand?, statut de l'invitatio? etc...) et de la relation inverse dans une autre table plutôt que de dupliquer ces infos.

J'ai donc maintenant trois Tables:
- accounts,
- relationships,
- et relationships_informations pour toutes les infos concernant la relation

Après quelques galères(j'ai rarement utilisé SQL directement au boulot) je suis arrivé à ce résultat:


-- # FUNCTIONS
-- ###########
CREATE FUNCTION reverse_relationship_informations_not_exists(
  account_id_a INTEGER, account_id_b INTEGER
) RETURNS BOOLEAN AS $$
BEGIN
    RETURN EXISTS(
        SELECT
            1
        FROM relationships_informations
        WHERE rship_account_a_id = account_id_b AND rship_account_b_id = account_id_a
    );
END;
$$
LANGUAGE plpgsql;


-- # TABLES
-- ########
CREATE TABLE accounts(
    id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
);

CREATE TABLE relationships(
    account_a_id INTEGER REFERENCES accounts (id),
    account_b_id INTEGER REFERENCES accounts (id),
    CONSTRAINT relationship_has_not_same_user CHECK (account_a_id != account_b_id),
    PRIMARY KEY (account_a_id, account_b_id)
);

CREATE TABLE relationships_informations(
    rship_account_a_id INTEGER,
    rship_account_b_id INTEGER,
    FOREIGN KEY (
        rship_account_a_id,
        rship_account_b_id
    ) REFERENCES relationships (account_a_id, account_b_id),
    reverse_rship_account_a_id INTEGER,
    reverse_rship_account_b_id INTEGER,
    FOREIGN KEY (
        reverse_rship_account_a_id,
        reverse_rship_account_b_id
    ) REFERENCES relationships (account_a_id, account_b_id),
    PRIMARY KEY(
        rship_account_a_id,
        rship_account_b_id,
        reverse_rship_account_a_id,
        reverse_rship_account_b_id
    ),

    CONSTRAINT relationships_has_same_users CHECK (
        rship_account_a_id = reverse_rship_account_b_id
        AND rship_account_b_id = reverse_rship_account_b_id
    ),
    CHECK (reverse_relationship_informations_not_exists(rship_account_a_id, rship_account_b_id)),

    -- Informations
    last_action_account_id INTEGER NOT NULL REFERENCES accounts (id),
    CONSTRAINT last_action_done_by_one_of_two_users CHECK(
        last_action_account_id IN (rship_account_a_id, rship_account_b_id)
    )
);


Je me retrouve avec une clé primaire composé de 4 colonnes pour la table relationships_informations, sachant que les 4 colonnes sont ni plus ni moins que deux id différents.
Et je me retrouve également obligé de vérifier que l'inverse de ma relationship_informations n'existe pas.

Y'a t'il un moyen plus intelligent de faire tout ca?

Pour infos j'utilise PostGres et j'ai enlevé pas mal de trucs inutiles concernant ma question.

[ Dernière édition du message le 20/02/2020 à 20:51:35 ]

1873
Je ne suis pas un expert en architecture de DB mais ça me semble super compliqué pour rien ton histoire.

Tu ne pourrais pas:

- avoir compte A / compte B / ID (un INT en auto increment utilisée pour la Primary Key) dans ta table relationship
- ajouter un contrainte d'unicité sur les deux colonnes compte A / compte B
- ajouter directement la contrainte de non existence de la relation inverse dans la table relationship
- mettre toutes infos sur la relation dans ta table relationship_informations en ayant pour seule contrainte l'ID de relationship en Foreign Key

Encore une fois je ne suis pas un spécialiste mais en procédant comme ça il me semble que tu vires une bonne partie de duplicata et de contraintes inutiles.
1874
Perso, identifier ton besoins en partant direct sur les CREATE TABLE ça me semble un peu compliqué.
Avant de modéliser, et pour notre (en tout cas la mienne) compréhension de ton objectif, je pense qu'il faudrait commencer par poser quelques questions basiques en mode texte du type :
- Un client peut-il avoir plusieurs fournisseurs ?
- Un fournisseur peut-il avoir plusieurs clients ?
- Un fournisseur à t'il plusieurs adresses ?
- etc...

ça permet d'identifier les relations 1,1 / 1,N / N,N pour ensuite construire un modèle relationnel...

[ Dernière édition du message le 20/02/2020 à 22:52:05 ]

1875
D’accord avec Krisfrom (et IPP aussi).


Citation :
Je me retrouve avec une clé primaire composé de 4 colonnes pour la table relationships_informations, sachant que les 4 colonnes sont ni plus ni moins que deux id différents.

Même si c’était déconseillé à l’époque de Merise, en pratique c’est bien d’ajouter et toujours avoir un identifiant entier unique dans une colonne. Ça simplifie pas mal d’opérations ; car j’imagine que tu vas exploiter ces tables depuis un langage de programmation classique.