[Tuto] Pilotage de moteur triphasé à faible vitesse

Cet article est inspiré du travail de BerryJam -> http://www.berryjam.eu/2015/04/driving-bldc-gimbals-at-super-slow-speeds-with-arduino/

L’objectif de cet article est de piloter un moteur triphasé à l’aide du module driver L6234 conçu par Letmeknow avec un Arduino Uno. Coté câblage, rien de plus simple:

Module Driver L6234Arduino
GNDGND
IN1D9
IN2D10
IN3D11
EN1D5
EN2D6
EN3D7
PWRVIN

Pour le moteur, on relie simplement les 3 phases sur les 3 broches P1, P2 et P3.

Coté logiciel, on va rester sur le code proposé par BerryJam:


//
// Slow and precise BLDC motor driver using SPWM and SVPWM modulation
// Part of code used from http://elabz.com/
// (c) 2015 Ignas Gramba www.berryjam.eu
//
 
 
const int EN1 = 5;
const int EN2 = 6;
const int EN3 = 7;
 
const int IN1 = 9;
const int IN2 = 10;
const int IN3 = 11;
 
 
// SPWM (Sine Wave)
//const int pwmSin[] = {127, 138, 149, 160, 170, 181, 191, 200, 209, 217, 224, 231, 237, 242, 246, 250, 252, 254, 254, 254, 252, 250, 246, 242, 237, 231, 224, 217, 209, 200, 191, 181, 170, 160, 149, 138, 127, 116, 105, 94, 84, 73, 64, 54, 45, 37, 30, 23, 17, 12, 8, 4, 2, 0, 0, 0, 2, 4, 8, 12, 17, 23, 30, 37, 45, 54, 64, 73, 84, 94, 105, 116 };
 
 
/// SVPWM (Space Vector Wave)
//const int pwmSin[] = {128, 147, 166, 185, 203, 221, 238, 243, 248, 251, 253, 255, 255, 255, 253, 251, 248, 243, 238, 243, 248, 251, 253, 255, 255, 255, 253, 251, 248, 243, 238, 221, 203, 185, 166, 147, 128, 109, 90, 71, 53, 35, 18, 13, 8, 5, 3, 1, 1, 1, 3, 5, 8, 13, 18, 13, 8, 5, 3, 1, 1, 1, 3, 5, 8, 13, 18, 35, 53, 71, 90, 109};
const int pwmSin[] = {128, 132, 136, 140, 143, 147, 151, 155, 159, 162, 166, 170, 174, 178, 181, 185, 189, 192, 196, 200, 203, 207, 211, 214, 218, 221, 225, 228, 232, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 249, 250, 250, 251, 252, 252, 253, 253, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 253, 252, 252, 251, 250, 250, 249, 248, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 249, 250, 250, 251, 252, 252, 253, 253, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 253, 252, 252, 251, 250, 250, 249, 248, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 235, 232, 228, 225, 221, 218, 214, 211, 207, 203, 200, 196, 192, 189, 185, 181, 178, 174, 170, 166, 162, 159, 155, 151, 147, 143, 140, 136, 132, 128, 124, 120, 116, 113, 109, 105, 101, 97, 94, 90, 86, 82, 78, 75, 71, 67, 64, 60, 56, 53, 49, 45, 42, 38, 35, 31, 28, 24, 21, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21, 24, 28, 31, 35, 38, 42, 45, 49, 53, 56, 60, 64, 67, 71, 75, 78, 82, 86, 90, 94, 97, 101, 105, 109, 113, 116, 120, 124};
 
int currentStepA;
int currentStepB;
int currentStepC;
int sineArraySize;
int increment = 0;
boolean direct = 1; // direction true=forward, false=backward
 
//////////////////////////////////////////////////////////////////////////////
 
void setup() {
 
  setPwmFrequency(IN1); // Increase PWM frequency to 32 kHz  (make unaudible)
  setPwmFrequency(IN2);
  setPwmFrequency(IN3);
 
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(IN3, OUTPUT); 
  
  pinMode(EN1, OUTPUT); 
  pinMode(EN2, OUTPUT); 
  pinMode(EN3, OUTPUT); 
 
 
  digitalWrite(EN1, HIGH);
  digitalWrite(EN2, HIGH);
  digitalWrite(EN3, HIGH);
  
 
  sineArraySize = sizeof(pwmSin)/sizeof(int); // Find lookup table size
  int phaseShift = sineArraySize / 3;         // Find phase shift and initial A, B C phase values
  currentStepA = 0;
  currentStepB = currentStepA + phaseShift;
  currentStepC = currentStepB + phaseShift;
 
  sineArraySize--; // Convert from array Size to last PWM array number
}
 
//////////////////////////////////////////////////////////////////////////////
 
void loop() {
 
  analogWrite(IN1, pwmSin[currentStepA]);
  analogWrite(IN2, pwmSin[currentStepB]);
  analogWrite(IN3, pwmSin[currentStepC]);  
  
  if (direct==true) increment = 1;
  else increment = -1;     
 
  currentStepA = currentStepA + increment;
  currentStepB = currentStepB + increment;
  currentStepC = currentStepC + increment;
 
  //Check for lookup table overflow and return to opposite end if necessary
  if(currentStepA > sineArraySize)  currentStepA = 0;
  if(currentStepA < 0)  currentStepA = sineArraySize;
 
  if(currentStepB > sineArraySize)  currentStepB = 0;
  if(currentStepB < 0)  currentStepB = sineArraySize;
 
  if(currentStepC > sineArraySize)  currentStepC = 0;
  if(currentStepC < 0) currentStepC = sineArraySize; 
  
  /// Control speed by this delay
  delay(10);
 
}
 
 
void setPwmFrequency(int pin) {
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | 0x01;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | 0x01;
    }
  }
  else if(pin == 3 || pin == 11) {
    TCCR2B = TCCR2B & 0b11111000 | 0x01;
  }
}

Pour aller plus loin, vous pouvez joué sur le SVPWM comme dans ce tuto https://electronics-project-hub.com/3-phase-sine-wave-generator-code-arduino/ et piloter la vitesse de votre moteur par un potentiomètre.

//-------www<electronics-project-hub>com--------//
#include <math.h>
int Output1 = 9;
int Output2 = 10;
int Output3 = 11;
const int EN1 = 5;
const int EN2 = 6;
const int EN3 = 7;
int potVal = 0;
float A = 0;
float B = 0.104;
int Freq_IN = A0;
int var1 = 0;
int var2 = 0;
int var3 = 0;
int var4 = 0;
int var5 = 0;
int var6 = 0;
float Phase1 = 2 * PI / 3;
float Phase2 = 4 * PI / 3;
float Phase3 = 2 * PI;
boolean toggle = true; // true = Enabling Serial Plotter Output
void setup()
{
  Serial.begin(9600);
  pinMode(Output1, OUTPUT);
  pinMode(Output2, OUTPUT);
  pinMode(Output3, OUTPUT);
  pinMode(Freq_IN, INPUT);
  pinMode(EN1, OUTPUT); 
  pinMode(EN2, OUTPUT); 
  pinMode(EN3, OUTPUT); 
  digitalWrite(EN1, HIGH);
  digitalWrite(EN2, HIGH);
  digitalWrite(EN3, HIGH);
}
void loop()
{
  A += B;
  analogWrite(Output1, var1);
  analogWrite(Output2, var2);
  analogWrite(Output3, var3);
  if (toggle == true)
  {
    Serial.print(var1);
    Serial.print(" ");
    Serial.print(var2);
    Serial.print(" ");
    Serial.println(var3);
  }
  var4 = 126 * sin(A + Phase1);
  var1 = var4 + 128;
  var5 = 126 * sin(A + Phase2);
  var2 = var5 + 128;
  var6 = 126 * sin(A + Phase3);
  var3 = var6 + 128;
  if (A >= 2 * PI)
  {
    A = 0;
  }
  potVal = analogRead(Freq_IN);
  delay(potVal);
}
//-------www<electronics-project-hub>com--------//

[Tuto] Mode sommeil sur Trinket

Les modes sommeil permettent de réduire énormément la consommation des cartes électroniques. Sur le Trinket d’Adafruit, il est souvent recommandé de passer par les librairies Adafruit_sleepydog dans cet exemple nous allons passer par l’utilisation d’une librairie plus bas niveau.

 

Le cœur de l’Adafruit Trinket est un microcontrôleur Attiny 85. Celui-ci est basé sur une architecture de type AVR. Nous allons donc passer dans notre cas par les librairies pour Arduino avr/sleep.h et avr/interrupt.h

Pour faire nos essais, nous allons nous baser sur le sketch exemple « Button » inclue dans l’IDE Arduino. Après quelques modifications de pinout, il est compatible avec le Trinket:

const int buttonPin = 0;     // the number of the pushbutton pin
const int ledPin =  1;      // the number of the LED pin</em></p>
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
   // initialize the LED pin as an output:
   pinMode(ledPin, OUTPUT);
   // initialize the pushbutton pin as an input:
   pinMode(buttonPin, INPUT);
}

void loop() {
   // read the state of the pushbutton value:
   buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
   if (buttonState == HIGH) {
     // turn LED on:
     digitalWrite(ledPin, HIGH);
   } else {
     // turn LED off:
     digitalWrite(ledPin, LOW);
   }
 }

Le mode sleep va fonctionner comme ceci:

  • Lorsque le bouton n’est pas pressé
  • La LED s’allume 3 secondes
  • Le mode sleep s’enclenche avec la LED qui reste allumée
  • Lors de l’appuie sur le bouton le Trinket sort du mode sleep

Voici le code que cela donne:

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
}

void sleep() {

    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT0);                   // Use PB0 as interrupt pin 0
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // sleep

    cli();                                  // Disable interrupts
    PCMSK &= ~_BV(PCINT0);                  // Turn off PB0 as interrupt pin
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on

    sei();                                  // Enable interrupts
    } // sleep

ISR(PCINT0_vect) {
    // This is called when the interrupt occurs, but I don't need to do anything in it
    }

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    delay(3000);
    sleep();
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

A titre de comparaison, sans le mode sleep LED allumée le Trinket consomme 22mA sous 12V avec le mode sleep cela tombe à 13mA soit une économie de 9mA

[Tuto] Dépannage station de soudure à air chaud

Les stations de soudure à air chaud sont devenues un indispensable pour assembler des composants CMS. Parmi les nombreuses références disponibles sur le marché des modèles entrée de gamme à 700/800W sont très présents sur le marché. Aujourd’hui nous vous expliquons comment les dépanner.

Les symptômes de pannes sont généralement au niveau du pistolet:

  • Non démarrage lors du retrait du socle
  • Problème de chauffe
  • Problème de flux d’air

Les modèles étant assez variés dans les connexions entre pistolet et station, voici la démarche que nous suivons pour le dépannage de nos modèles (YOUYUE 8586 et SAIKE 898D):

  • Ouvrir le pistolet
  • Réaliser le mapping
Sur le YOUYUE 8586:
1Temp sensor
2Commun sensor
3Capteur reed
4Masse
5GND fan
6VCC fan
7Blanc cartouche chauffe
8Rouge cartouche de chauffe
  • Remplacer le composant défectueux
  • Remonter le tout

[Debug] Convertisseur USB UART

Les convertisseurs USB UART les plus répandus pour Arduino sont sur base de PL2303. Ce composant est conçu par Prolific. De très nombreuses versions existent sur internet, voici le process que l’on a validé sur nos postes.

Etape 1: Installer le driver

Le driver en question est disponible ici: Driver Prolific

Installez le sur votre ordinateur.

Etape 2: Forcer l’installation de ce Driver

Ouvrez le gestionnaire de périphériques (Sous Windows, cliquez sur Démarrer puis écrivez « Gestionnaire » il devrait apparaître).

Vous devriez avoir quelque chose comme cela:

Cliquez droit sur « USB-Serial Controller » puis « Mettre à jour le pilote »

Choisissez « Parcourir mon ordinateur à la recherche du logiciel de pilote ».

Cliquez ensuite sur « Choisir parmi une liste de pilotes disponibles sur mon ordinateur »

Dans la liste, choisissez « Ports (COM et LPT) »

Vous pouvez ensuite avoir plusieurs versions de pilote. Il faut choisir le 3.3.2.105

L’installation se lance puis votre module est fonctionnel.

[Tuto] Rétro Pi sur Raspberry Pi 2

Aujourd’hui nous ajoutons au catalogue des manettes rétros de NES, l’occasion parfait de vous parler de Rétro Pi.

Rétro Pi est une distribution pour Raspberry Pi ayant pour but d’émuler d’anciennes consoles de jeux vidéos. Ces distributions sont compatibles tous Raspberry Pi, et permettent de gérer les manettes USB comme les extensions pour boutons d’arcades et joysticks. Nous allons l’installer sur un Raspberry Pi 2 avec 2 manettes NES en USB.

Première étape: Télécharger l’image Retro Pi

Le site Rétro Pi propose une page pour télécharger les différentes images existantes: https://retropie.org.uk/download/

Comme d’habitude, choisissez une carte SD suffisamment grande (4Go dans notre cas), formatez la et gravez l’image dessus.

Deuxième étape: Paramétrer les manettes

Au démarrage de votre Raspberry Pi, celui-ci détecte les manettes et vous propose de les paramètrer.

welcomescreen

Troisième étape: Ajouter quelques ROMs

Pour cela de nombreux sites permettent de télécharger les ROMs de vos jeux favoris. En voici un exemple: http://www.freeroms.com

Pour les ajouter à votre Retro Pi, voici les étapes à suivre:

  • Formater une clé USB (FAT32)
  • Créer un répertoire « retropie » avec votre ordinateur
  • Brancher la clé au Raspberry Pi
  • Attendre qu’elle arrête de clignoter
  • Débrancher du Raspberry Pi et rebrancher à votre ordinateur
  • Des répertoires ont dû être créés, vous pouvez vos ROMS dans « retropie/roms » (attention à bien choisir la console en question)
  • Rebrancher la clé au Raspberry Pi
  • Attendre qu’elle arrête de clignoter
  • Redémarrer la console (Menu « restart emulationstation »)

Profitez!

retropie-original-flat-outline

[Tuto][API] Utiliser l’API Twitter via PHP

Dans cet article, nous utiliserons l’API Twitter grace au langage PHP. Cet article s’inscrit dans la continuité de celui permettant de récupérer uniquement le nombre de followers.

Toute la méthode expliquée ci-dessous est basé sur cet article: http://iag.me/socialmedia/build-your-first-twitter-app-using-php-in-8-easy-steps/

Nous utilisons le système suivant: https://github.com/J7mbo/twitter-api-php

Dans l’index.php, vous aurez à personnaliser les lignes:

$settings = array(
 'oauth_access_token' => "OAUTH_ACCESS_TOKEN",
 'oauth_access_token_secret' => "OAUTH_ACCESS_TOKEN_SECRET",
 'consumer_key' => "CONSUMER_KEY",
 'consumer_secret' => "CONSUMER_SECRET"
 );

Tous ces paramètres sont disponibles en créant une application sur le site https://apps.twitter.com

Pour récupérer les informations principales du compte: le nombre de followers, le nombre d’abonnements et le nombre de tweets

twitter

<?php
ini_set('display_errors', 1);
require_once('Twitter/TwitterAPIExchange.php');

$settings = array(
'oauth_access_token' => "YOUR_ACCESS_TOKEN",
'oauth_access_token_secret' => "YOUR_ACCESS_TOKEN_SECRET",
'consumer_key' => "YOUR_CONSUMMER_KEY",
'consumer_secret' => "YOUR_CONSUMER_SECRET"
);

$url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
 
$requestMethod = "GET";
 
$getfield = '?screen_name=LetmeknowFr&count=1';
 
$twitter = new TwitterAPIExchange($settings);
$string = json_decode($twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest(),$assoc = TRUE);
if($string["errors"][0]["message"] != "") {echo "<h3>Sorry, there was a problem.</h3><p>Twitter returned the following error message:</p><p><em>".$string[errors][0]["message"]."</em></p>";exit();}
foreach($string as $items) {
$followers = $items['user']['followers_count'];
$friends = $items['user']['friends_count'];
$tweets = $items['user']['statuses_count'];
}
?>

De nombreux autres data sont récupérables, elles sont détaillées dans l’article http://iag.me/socialmedia/build-your-first-twitter-app-using-php-in-8-easy-steps/

[Tuto][API] Récupérer le nombre de followers Twitter facilement

Sur le même concept que la récupération du nombre de fans Facebook, il est possible de connaitre le nombre de followers d’une page Twitter. Nous fonctionnons avec une page Php qui affiche uniquement un nombre correspondant au nombre de Followers (Ci dessous avec la page LetmeknowFr)

<html>
<body>
<?php 
$tw_username = 'LetmeknowFr'; 
$data = file_get_contents('http://cdn.syndication.twimg.com/widgets/followbutton/info.json?screen_names='.$tw_username); 
$parsed = json_decode($data,true);
$tw_followers = $parsed[0]['followers_count'];
echo $tw_followers;
?>
</body>
</html>

A vous de créer l’objet pour visualiser cette donnée!

19708_smiirl-va-decliner-son-compteur-de-likes-sur-instagram-et-twitter

[Tuto][API] Récupérer le nombre de fan Facebook facilement

Parfois lors de la réalisation d’un objet connecté, il peut être intéressant de récupérer différentes informations de Facebook comme le nombre de Fans. Avec cette information, vous pouvez réaliser un compteur à la manière de celui de Smiirl

smiirl-facebook-like-count-7

Vous pouvez aussi créer des interactions comme cette Lampe de Seeedstudio

FUP5MMDIHQOBV42.MEDIUM

La méthode que nous vous proposons est d’utiliser un script php qui vous retournera directement la valeur de likes, fans ou autres que vous recherchez.

Dans ce premier exemple vous récupérerez le nombre de fan de la page Letmeknow (id 477204119057198). Vous pouvez récupérer l’ID de votre fan page sur ce site http://findmyfbid.com

<html>
<body>
<?php 
 $xml = simplexml_load_file("http://api.facebook.com/restserver.php?method=facebook.fql.query&query=SELECT%20fan_count%20FROM%20page%20WHERE%20page_id=477204119057198"); 
 echo $xml->page->fan_count;
 ?>
</body>
</html>

Nous avons également expérimenté une autre donnée intéressante de Facebook qui est le nombre de partage d’une page Web. Dans cet exemple la page letmeknow.fr

<html>
<body>
<?php 
 $xml = simplexml_load_file("http://api.facebook.com/method/links.getStats?urls=letmeknow.fr"); 
 echo $xml->link_stat->total_count;
 ?>
</body>
</html>

[Tuto] Premier programme avec l’API Particle

Nous allons voir comment utiliser simplement l’API Particle depuis son navigateur. L’objectif va être d’allumer à distance une LED raccordée à un Particle Electron, cela fonctionne de la même manière pour le Core et Photon.

Programme de la carte

Pour le programme à injecter dans l’Electron, on se repose sur l’exemple « web-connected-led.ino »

// -----------------------------------
// Controlling LEDs over the Internet
// -----------------------------------

int led1 = D0;
int led2 = D7;

void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);

Particle.function("led",ledToggle);

digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
}

void loop()
{
}

int ledToggle(String command) {

if (command=="on") {
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
return 1;
}
else if (command=="off") {
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
return 0;
}
else {
return -1;
}
}

Ce programme va automatiquement créer la requête correspondante à la fonction « led ».

Première méthode par utilisation d’une page Web

Nous allons créer un formulaire Web « test.html » dans l’optique d’utiliser la méthode POST dans une page Web. Nous reprenons également la page Web proposé par le tutoriel Particle.

<!-- Replace your-device-ID-goes-here with your actual device ID and replace your-access-token-goes-here with your actual access token-->
<!DOCTYPE>
<html>
<body>
<center>
<form action="https://api.particle.io/v1/devices/your-device-ID-goes-here/led?access_token=your-access-token-goes-here" method="POST">
Tell your device what to do!<br> <br> 
<input type="radio" name="args" value="on">Turn the LED on. <br>
<input type="radio" name="args" value="off">Turn the LED off. <br> <br>
<input type="submit" value="Do it!">
</form>
</center>
</body>
</html>

La réponse reçue après validation du formulaire est du type:

{
  "id": "your-device-ID-goes-here",
  "last_app": "",
  "connected": true,
  "return_value": 1
}

Deuxième méthode par utilisation d’une Chrome App

Il existe sur Chrome des applications permettant de réaliser toutes sortes de choses. Aujourd’hui nous nous intéresserons à l’application Advanced Rest Client. Elle permet de réaliser simplement des requêtes API de type POST.

App chrome