Découvrez notre Chaîne YouTube "Ingénierie et Projets"
Découvrez notre Chaîne Secondaire "Information Neuronale et l'Ingénierie du Cerveau"

Objectifs du projet

    1. Savoir comment lire les informations d’une carte mémoire
    2. Savoir comment lire un fichier dans la carte SD
    3. Savoir comment créer un nouveau fichier
    4. Savoir comment mettre à jour un fichier de données
    5. Savoir comment formater les données dans un fichier
    6. Savoir dater, et stocker les données dans la carte mémoire
    7. Savoir utiliser une carte mémoire avec Arduino
    8. Savoir développer un Data logger avec Arduino
    9. Etc.

Fonctionnement du projet

L’objectif projet et l’acquisition et stockage des données dans une carte mémoire. On fait la lecture du pin analogique A0 toute les secondes. On utilise un buffer (tableau) pour le stockage local dans la carte Arduino. Après le remplissage du tableau, on transfert ce dernier à la carte mémoire SD. On peut varier la taille du tableau via le paramètre N. Chaque ligne du fichier contient la donnée en format double séparé par des virgules ainsi la date et l’heure d’acquisition de ce dernier à la fin de la ligne. Ci-dessous le format de stockage des données dans les lignes du fichier:

DATA1,…, DATAN, Année, …, Secondes,

DATA1,…, DATAN, Année, …, Secondes,

DATA1,…, DATAN, Année, …, Secondes,

DATA1,…, DATAN, Année, …, Secondes,

….

Capteur et module RTC

Avant d’abordé le projet, je vous recommande de consulter la partie 1 et 2 du projet concernant la partie capteur et le module RTC pour la sauvegarde du temps.

Lecteur de la carte SD

Le lecteur de la carte MicroSD utilise l’interface SPI pour interfacer avec la carte Arduino via les pins SCK (Horloge), MOSI (Master Out Slave  In) pour l’envoie des données vers de la carte Arduino vers le module et MISO (Master In Slave  Out) pour la récupération des données de la carte. L’interface SPI est une interface synchrone, il utilise un signal d’horloge indépendant. Le pin CS est utilisé pour l’activation du module de la carte SD. Il est activé niveau : Il faut positionner le pin à 5V afin d’activer le lecteur. Le pin CS est très important lorsqu’on a besoin de contrôler plusieurs lecteurs avec une seule interface. Par exemple, si on dispose de 3 cartes SD de 34 Go, alors on peut sélectionner une carte à la fois grâce aux pins CS1, CS2 et CS1 !

Le lecteur est alimente par une alimentation de 5V s’il dispose d’un régulateur interne comme le modèle illustré ci-dessous. Dans le cas échéant, la tension d’alimentation est souvent 3.3V ! Il faut bien s’assurer des caractéristiques de son lecteur avant d’effectuer le câblage au risque de détériorer le lecteur ou le sous alimentation de ce dernier. Un lecteur de 5V alimenté par 3.3V risque de ne pas fonctionner!

La module ci-dessous est testé et fonctionnel avec une carte Micro SD de 4 Go et 64 Go (voir la vidéo pour plus des détails).  Avant d’incruster la puce dans le lecteur, assurez-vous bien qu’elle est bien formater avec le système FAT16 ou FAT32. Il est recommandé aussi d’avoir une carte dédiée pour son stockage des données. Ci-dessous un lien vers un mini logiciel pour le formatage en format FAT32. Vous pouvez trouver d’autres logiciels dans le web en cas du besoin.

Télécharger le logiciel FAT32 Format

Lecteur carte SD

C’est  quoi la différence entre FAT16 et FAT32 ?

FAT16 (File Allocation Table), soit « table d’allocation de fichiers, ce de divise l’espace disponible sur un disque dur ou mémoire SD en 65536 blocs (ou clusters)  portant chacun un numéro propre. Si le nombre de blocs reste constant, leur taille varie en fonction de la taille du périphérique de stockage. À partir de Windows 95 OSR2, l’utilisateur a le choix entre FAT16 et FAT32. Ce système de fichiers est également utilisé sur les cartes SD. FAT16 permet d’avoir des partitions, selon la taille des clusters, occupant jusqu’à 2 Go, et exceptionnellement 4 Go. Concrètement, les spécifications  de FAT16 sont les suivantes :

  • Taille maximale d’un fichier : 4 Go – 1 octet (soit exactement 4 294 967 295 octets) ;
  • Nombre maximal de fichiers par partition : 65 524 ;
  • La racine du disque est de plus limitée à 512 entrées ; une entrée est un fichier ou un dossier, lire la suite…
  • Taille maximale de la mémoire 2 To !

A retenir,  au moment de stockage des donnés dans la carte SD,  la taille du fichier ne doit pas dépasse au maximum 4Go. Il faut mettre en place un système de création des fichiers dans la carte SD avec une taille modérée (voir la vidéo et la suite de l’article). En cas de dépassement de la capacité, il peut la remise à zéro du pointeur des lignes du fichier (écraser les données anciennes).

Tout savoir sur le système des fichiers FAT32

Schéma de câblage avec la carte Arduino

Le lecteur de carte SD utilise l’interface SPI matériel. Il faut  utiliser les mêmes pins  en fonction de votre carte Arduino. Le câblage est différent pour la carte Arduino Méga. Voir le tableau et les figures ci-dessous pour plus des détails.

Cablage SD avec Arduino

aRDUINO UNO Projet Data logger Gestion de la mémoire SD avec Arduino

La fonction setup()

void setup() 
{  
  // Init INT4
  InitInt4(PinINT4); 

  // Initialisation du port série: Affichage locale des données  
  Serial.begin(9600); 

  // Initialisation du Module RTC (Heure de l'ordinateur) 
  InitRTC();
  
  // Initialisation de la carte SD
  InitSD(CS); 

  // Stockage des données dans le fichier (Fichier par défaut)
  WriteSD(Data, DateHeure, N,  NomFichier);

  // Réouverture et Affichage du contenu du fichier (Fichier par défaut)
  ReadDisFile(NomFichier);

}

La fonction loop():

Lecture de l’horloge RTC

void loop() 
{
  //Lecture de l'horloge 
  GetDateHeure(DateHeure);
}

La fonction ISR():

Acquisition et stockage des données

ISR(INT4_vect) //ISR(_VECTOR(5))
{ 
  // Compteur des échantillons 
  static long count=0; 
  
  // Désactivation de l'interruption globale 
  cli(); 
  
  // Lecture du capteur de luminosité  
  R_l= GetData(A0); 
  
  // Mise à jour du buffer des échantillons  
  Data[count]=R_l; 

  // Mise à jour du compteur 
  count++; count=count%N;
  
  // Mise à jour du nom du fichier 
  NomFichier= UpdateNomFile(TFile, DateHeure, NomFichier);

  
  // Stockage des données dans la carte Mémoire 
  if(!count) //count=N: stockage lorsque le buffer est plein  
  {
    // Stockage des données dans la carte SD
    WriteSD(Data, DateHeure, N, NomFichier); 
    
    // Réouverture et Affichage du contenu du fichier (Pour la vérification)
    Serial.println(NomFichier);
    ReadDisFile(NomFichier);
  }
  
  // Réactivation de l'interruption globale 
  sei();
}

La fonction ReadDisFile()

Lecture et affichage du contenu d’un fichier dans la carte SD

void ReadDisFile(String NomFich)
{
  // 1. Réouverture du fichier 
  myFile = SD.open(NomFich);
  
  if (myFile) 
  {
    // 2. Lecture & Affichage du contenu du fichier 
    while (myFile.available()) {
      Serial.write(myFile.read());
    }

    // 3. Fermeture du fichier 
    myFile.close();
  } else 
  {
    Serial.println("Erreur d'ouverture du fichier "+ NomFich);
  }
  Serial.println("\n\n");
}

La fonction UpdateNomFile()

Génération périodique d’un nom du fichier en fonction de la date, l’heure et la période de création d’un nouveau fichier

String UpdateNomFile(byte TempsFile, word *Horloge, String OldName)
{
  String NewNom=""; 
  unsigned long T; 
  T=Horloge[0]+60*Horloge[1]+60*60*Horloge[2]; 

  
  if(!(T%TempsFile)) // Changement du nom du fichier toutes les  TempsFile
  {
    for(int i=3;i>=0;i--)
    {
      NewNom=NewNom+String(Horloge[i]); 
    }
    NewNom="F"+NewNom+".txt"; 
  } 
  else 
    NewNom=OldName; 
  
  return NewNom;
}

La fonction WriteSD()

Stockage d’un buffer de taille N dans le fichier courant avec la date et l’heure

void WriteSD(double *DataIn, word *Horloge, int Taille, String NomFich)
{
  String StrDATA="";
  
  // 1. Ouverture du fichier en écriture 
  File myFile = SD.open(NomFich, FILE_WRITE);
  
  // 2-3. Conversion et Stockage des données dans la carte mémoire 
  if (myFile) 
  { 
    // Données 
    for(int i=0;i<Taille; i++)
    {
      // 2. Conversion des données en chaine de caractaire 
      StrDATA=String(DataIn[i])+",";
    
      // 3. Stockage dans la carte SD
      myFile.print(StrDATA);
    }

    // Date & Heure  
    for(int i=0;i<6; i++)
    {
      // 2. Conversion des données en chaîne de caractère 
      StrDATA=String(Horloge[i])+",";
    
      // 3. Stockage dans la carte SD
      myFile.print(StrDATA);
    }
 
    myFile.print("\n"); // Retour à la ligne 
  
    // 4. Fermeture du fichier 
    myFile.close();
  } 
  else 
  {
    Serial.println("Erreur d'ouverture du fichier "+NomFichier);
  }
}

La fonction GetDateHeure()

Récupération de la date et l’heure dans le module RTC

void GetDateHeure(word *DateHeure)
{
  // Lecture du module RTC
  DateTime now = rtc.now();

  // Récupération de la date 
  DateHeure[5]=now.year();        // Années
  DateHeure[4]=now.month();       // Mois
  DateHeure[3]=now.day();         // Jours 

  // Récupération de l'heure 
  DateHeure[2]=now.hour();
  DateHeure[1]=now.minute();
  DateHeure[0]=now.second();
}

La fonction InitRTC()

Initialisation du module RTC avec la génération d’un signal carré de 1Hz. Il sera utilisé pour trigger les acquisitions et le  stockage des données

void InitRTC(void)
{
  if (! rtc.begin()) 
  {
    Serial.println("Le module RTC non disponible");
    while (1); // Attente RESET
  }
  else
  {
    Serial.println("Le module RTC est OK");
    rtc.writeSqwPinMode(DS1307_SquareWave1HZ);
      //DS1307_SquareWave1HZ = 0x10,  // 1Hz square wave
      //DS1307_SquareWave4kHz = 0x11, // 4kHz square wave
      //DS1307_SquareWave8kHz = 0x12, // 8kHz square wave
      //DS1307_SquareWave32kHz = 0x13 // 32kHz square wave
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Date du PC

    //rtc.adjust(DateTime(2020,1,24,10,10,10));     // Ajustement manuel 
    // Ex: 10 Janvier 2020 à 10:00:00:
    // rtc.adjust(DateTime(2020, 1, 10, 10, 0, 0));
  }
}

La fonction InitInt4()

Initialisation de l’interruption externe INT4 (Arduino Mega)

void InitInt4(byte PinINT)
{
  // Entrée de synchronisation 1PPS / INT4 
  pinMode(PinINT, INPUT); 

  // Activation de l'interruption globale (registre SREG)  
  SREG|=0x80;  

  // Validation de l'interruption INT4 (Registre EIMSK)
  EIMSK|=0x10; // INT4 
  
  // Choix du mode de détection: Front montant dans INT4 
  EICRB|=0x03;
}

La fonction InitSD()

Initialisation de la carte SD: Vérification de la connexion, affichage des informations de la carte, les fichiers disponibles dans la carte, test lecture et écriture dans la mémoire, etc.

void InitSD(byte ShipSel)
{
  // Positionner à "1" le CS: Activation du module 
  pinMode(ShipSel, OUTPUT);
  digitalWrite(ShipSel, HIGH); 

  // Initialisation 
  Serial.print("\n Initialisation de la carte SD...");

  if (!card.init(SPI_HALF_SPEED, CS)) {
    Serial.println("Initialisation échouée");
    //return;
  } else {
    Serial.println("Le câblage est OK et la carte est disponible.");
  }

  Serial.print("\nType de la carte: ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Non reconnue!");
  }

  if (!volume.init(card)) {
    Serial.println("La partition FAT16/FAT32 non dispo.\n Assurez-vous bien de bien formater la carte");
    return;
  }

  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();

  volumesize = volume.blocksPerCluster();    // clusters = somme des  blocks
  volumesize *= volume.clusterCount();       
  volumesize *= 512;                          // les blocs ont souvent la taille de 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);


  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  root.ls(LS_R | LS_DATE | LS_SIZE);

  if (!SD.begin(CS)) {
    Serial.println("Initialisation échouée!");
    while (1);
  }
  Serial.println("Initialisation réussie.");
}

La fonction GetData()

Lecture du flux de lumière (la résistance en fonction de la luminosité)

double GetData(byte Analog_pin)
{
  word A0_val; 
  double V0, R_ll; 
  
  // Lecture du capteur 
  A0_val=analogRead(Analog_pin); 
  
  // Conversion en volt [0,1023]=>[0, 5V] 
  V0=(double)A0_val*V/1023.00; 
  
  // Calcul de la résistance en Ohm 
  R_ll=((V/V0)-1.0)*R;
  
  // Renvoie de la valeur 
  return R_ll;
}

Le programme complet


/*

 * Projet Data logger: Stockage des données dans la carte SD 3/4  
 * wwww.Electronique-Mixte.fr
 
Objectifs
  1. Savoir utiliser le lecteur de la carte SD
  2. Savoir lire / écrire les données dans la carte SD
  3. Savoir ajuster la période de mise à jour du fichier  
  4. Savoir ajuster la période de création d’un nouveau fichier  
  5. Les erreurs fatales à éviter (Gagnez quelques heures ou jours du travail!)  
  6. Etc. 
*/

#include  <Wire.h>
#include  "RTClib.h"
#include  <SPI.h>
#include  <SD.h>
#define   CS  10
#define   V         5.00
#define   R         10000.0
#define   N         36      // 60*20=1200 - Taille SRAM 
#define   PinINT4   2       // PE4 - PIN 2 
#define   TFile     3600     // Création d'un nouveau fichier toutes 

RTC_DS1307 rtc;
word DateHeure[6]={0,0,0,0,0,0};
double R_l=0.0, Data[N];


Sd2Card card;
SdVolume volume;
SdFile root;

File myFile;
String StrDATA=""; 
String NomFichier="F1234"; // Fichier Initial (A ne pas tenir en compte) 

void setup() 
{  
  // Init INT4
  InitInt4(PinINT4); 

  // Initialisation du port série: Affichage locale des données  
  Serial.begin(9600); 

  // Initialisation du Module RTC (Heure de l'ordinateur) 
  InitRTC();
  
  // Initialisation de la carte SD
  InitSD(CS); 

  // Stockage des données dans le fichier (Fichier par défaut)
  WriteSD(Data, DateHeure, N,  NomFichier);

  // Réouverture et Affichage du contenu du fichier (Fichier par défaut)
  ReadDisFile(NomFichier);

}




void loop() 
{
  //Lecture de l'horloge 
  GetDateHeure(DateHeure);
}


ISR(INT4_vect) //ISR(_VECTOR(5))
{ 
  // Compteur des échantillons 
  static long count=0; 
  
  // Désactivation de l'interruption globale 
  cli(); 
  
  // Lecture du capteur de luminosité  
  R_l= GetData(A0); 
  
  // Mise à jour du buffer des échantillons  
  Data[count]=R_l; 

  // Mise à jour du compteur 
  count++; count=count%N;
  
  // Mise à jour du nom du fichier 
  NomFichier= UpdateNomFile(TFile, DateHeure, NomFichier);

  
  // Stockage des données dans la carte Mémoire 
  if(!count) //count=N: stockage lorsque le buffer est plein  
  {
    // Stockage des données dans la carte SD
    WriteSD(Data, DateHeure, N, NomFichier); 
    
    // Réouverture et Affichage du contenu du fichier (Pour la vérification)
    Serial.println(NomFichier);
    ReadDisFile(NomFichier);
  }
  
  // Réactivation de l'interruption globale 
  sei();
}

void ReadDisFile(String NomFich)
{
  // 1. Réouverture du fichier 
  myFile = SD.open(NomFich);
  
  if (myFile) 
  {
    // 2. Lecture & Affichage du contenu du fichier 
    while (myFile.available()) {
      Serial.write(myFile.read());
    }

    // 3. Fermeture du fichier 
    myFile.close();
  } else 
  {
    Serial.println("Erreur d'ouverture du fichier "+ NomFich);
  }
  Serial.println("\n\n");
}

String UpdateNomFile(byte TempsFile, word *Horloge, String OldName)
{
  String NewNom=""; 
  unsigned long T; 
  T=Horloge[0]+60*Horloge[1]+60*60*Horloge[2]; 

  
  if(!(T%TempsFile)) // Changement du nom du fichier toutes les  TempsFile
  {
    for(int i=3;i>=0;i--)
    {
      NewNom=NewNom+String(Horloge[i]); 
    }
    NewNom="F"+NewNom+".txt"; 
  } 
  else 
    NewNom=OldName; 
  
  return NewNom;
}
void WriteSD(double *DataIn, word *Horloge, int Taille, String NomFich)
{
  String StrDATA="";
  
  // 1. Ouverture du fichier en écriture 
  File myFile = SD.open(NomFich, FILE_WRITE);
  
  // 2-3. Conversion et Stockage des données dans la carte mémoire 
  if (myFile) 
  { 
    // Données 
    for(int i=0;i<Taille; i++)
    {
      // 2. Conversion des données en chaine de caractaire 
      StrDATA=String(DataIn[i])+",";
    
      // 3. Stockage dans la carte SD
      myFile.print(StrDATA);
    }

    // Date & Heure  
    for(int i=0;i<6; i++)
    {
      // 2. Conversion des données en chaîne de caractère 
      StrDATA=String(Horloge[i])+",";
    
      // 3. Stockage dans la carte SD
      myFile.print(StrDATA);
    }
 
    myFile.print("\n"); // Retour à la ligne 
  
    // 4. Fermeture du fichier 
    myFile.close();
  } 
  else 
  {
    Serial.println("Erreur d'ouverture du fichier "+NomFichier);
  }
}




void GetDateHeure(word *DateHeure)
{
  // Lecture du module RTC
  DateTime now = rtc.now();

  // Récupération de la date 
  DateHeure[5]=now.year();        // Années
  DateHeure[4]=now.month();       // Mois
  DateHeure[3]=now.day();         // Jours 

  // Récupération de l'heure 
  DateHeure[2]=now.hour();
  DateHeure[1]=now.minute();
  DateHeure[0]=now.second();
}

void InitRTC(void)
{
  if (! rtc.begin()) 
  {
    Serial.println("Le module RTC non disponible");
    while (1); // Attente RESET
  }
  else
  {
    Serial.println("Le module RTC est OK");
    rtc.writeSqwPinMode(DS1307_SquareWave1HZ);
      //DS1307_SquareWave1HZ = 0x10,  // 1Hz square wave
      //DS1307_SquareWave4kHz = 0x11, // 4kHz square wave
      //DS1307_SquareWave8kHz = 0x12, // 8kHz square wave
      //DS1307_SquareWave32kHz = 0x13 // 32kHz square wave
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Date du PC

    //rtc.adjust(DateTime(2020,1,24,10,10,10));     // Ajustement manuel 
    // Ex: 10 Janvier 2020 à 10:00:00:
    // rtc.adjust(DateTime(2020, 1, 10, 10, 0, 0));
  }
}


void InitInt4(byte PinINT)
{
  // Entrée de synchronisation 1PPS / INT4 
  pinMode(PinINT, INPUT); 

  // Activation de l'interruption globale (registre SREG)  
  SREG|=0x80;  

  // Validation de l'interruption INT4 (Registre EIMSK)
  EIMSK|=0x10; // INT4 
  
  // Choix du mode de détection: Front montant dans INT4 
  EICRB|=0x03;
}


void InitSD(byte ShipSel)
{
  // Positionner à "1" le CS: Activation du module 
  pinMode(ShipSel, OUTPUT);
  digitalWrite(ShipSel, HIGH); 

  // Initialisation 
  Serial.print("\n Initialisation de la carte SD...");

  if (!card.init(SPI_HALF_SPEED, CS)) {
    Serial.println("Initialisation échouée");
    //return;
  } else {
    Serial.println("Le câblage est OK et la carte est disponible.");
  }

  Serial.print("\nType de la carte: ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Non reconnue!");
  }

  if (!volume.init(card)) {
    Serial.println("La partition FAT16/FAT32 non dispo.\n Assurez-vous bien de bien formater la carte");
    return;
  }

  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();

  volumesize = volume.blocksPerCluster();    // clusters = somme des  blocks
  volumesize *= volume.clusterCount();       
  volumesize *= 512;                          // les blocs ont souvent la taille de 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);


  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  root.ls(LS_R | LS_DATE | LS_SIZE);

  if (!SD.begin(CS)) {
    Serial.println("Initialisation échouée!");
    while (1);
  }
  Serial.println("Initialisation réussie.");
}

double GetData(byte Analog_pin)
{
  word A0_val; 
  double V0, R_ll; 
  
  // Lecture du capteur 
  A0_val=analogRead(Analog_pin); 
  
  // Conversion en volt [0,1023]=>[0, 5V] 
  V0=(double)A0_val*V/1023.00; 
  
  // Calcul de la résistance en Ohm 
  R_ll=((V/V0)-1.0)*R;
  
  // Renvoie de la valeur 
  return R_ll;
}

Ressources PDF

Accueil des projets avec Arduino

Click to rate this post!
[Total: 1 Average: 5]

0 commentaire

Laisser un commentaire

Avatar placeholder

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Anti-Robot *

We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners.
Cookies settings
Accept
Decline
Privacy & Cookie policy
Privacy & Cookies policy
Cookie name Active

Privacy Policy

What information do we collect?

We collect information from you when you register on our site or place an order. When ordering or registering on our site, as appropriate, you may be asked to enter your: name, e-mail address or mailing address.

What do we use your information for?

Any of the information we collect from you may be used in one of the following ways: To personalize your experience (your information helps us to better respond to your individual needs) To improve our website (we continually strive to improve our website offerings based on the information and feedback we receive from you) To improve customer service (your information helps us to more effectively respond to your customer service requests and support needs) To process transactions Your information, whether public or private, will not be sold, exchanged, transferred, or given to any other company for any reason whatsoever, without your consent, other than for the express purpose of delivering the purchased product or service requested. To administer a contest, promotion, survey or other site feature To send periodic emails The email address you provide for order processing, will only be used to send you information and updates pertaining to your order.

How do we protect your information?

We implement a variety of security measures to maintain the safety of your personal information when you place an order or enter, submit, or access your personal information. We offer the use of a secure server. All supplied sensitive/credit information is transmitted via Secure Socket Layer (SSL) technology and then encrypted into our Payment gateway providers database only to be accessible by those authorized with special access rights to such systems, and are required to?keep the information confidential. After a transaction, your private information (credit cards, social security numbers, financials, etc.) will not be kept on file for more than 60 days.

Do we use cookies?

Yes (Cookies are small files that a site or its service provider transfers to your computers hard drive through your Web browser (if you allow) that enables the sites or service providers systems to recognize your browser and capture and remember certain information We use cookies to help us remember and process the items in your shopping cart, understand and save your preferences for future visits, keep track of advertisements and compile aggregate data about site traffic and site interaction so that we can offer better site experiences and tools in the future. We may contract with third-party service providers to assist us in better understanding our site visitors. These service providers are not permitted to use the information collected on our behalf except to help us conduct and improve our business. If you prefer, you can choose to have your computer warn you each time a cookie is being sent, or you can choose to turn off all cookies via your browser settings. Like most websites, if you turn your cookies off, some of our services may not function properly. However, you can still place orders by contacting customer service. Google Analytics We use Google Analytics on our sites for anonymous reporting of site usage and for advertising on the site. If you would like to opt-out of Google Analytics monitoring your behaviour on our sites please use this link (https://tools.google.com/dlpage/gaoptout/)

Do we disclose any information to outside parties?

We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our website, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.

Registration

The minimum information we need to register you is your name, email address and a password. We will ask you more questions for different services, including sales promotions. Unless we say otherwise, you have to answer all the registration questions. We may also ask some other, voluntary questions during registration for certain services (for example, professional networks) so we can gain a clearer understanding of who you are. This also allows us to personalise services for you. To assist us in our marketing, in addition to the data that you provide to us if you register, we may also obtain data from trusted third parties to help us understand what you might be interested in. This ‘profiling’ information is produced from a variety of sources, including publicly available data (such as the electoral roll) or from sources such as surveys and polls where you have given your permission for your data to be shared. You can choose not to have such data shared with the Guardian from these sources by logging into your account and changing the settings in the privacy section. After you have registered, and with your permission, we may send you emails we think may interest you. Newsletters may be personalised based on what you have been reading on theguardian.com. At any time you can decide not to receive these emails and will be able to ‘unsubscribe’. Logging in using social networking credentials If you log-in to our sites using a Facebook log-in, you are granting permission to Facebook to share your user details with us. This will include your name, email address, date of birth and location which will then be used to form a Guardian identity. You can also use your picture from Facebook as part of your profile. This will also allow us and Facebook to share your, networks, user ID and any other information you choose to share according to your Facebook account settings. If you remove the Guardian app from your Facebook settings, we will no longer have access to this information. If you log-in to our sites using a Google log-in, you grant permission to Google to share your user details with us. This will include your name, email address, date of birth, sex and location which we will then use to form a Guardian identity. You may use your picture from Google as part of your profile. This also allows us to share your networks, user ID and any other information you choose to share according to your Google account settings. If you remove the Guardian from your Google settings, we will no longer have access to this information. If you log-in to our sites using a twitter log-in, we receive your avatar (the small picture that appears next to your tweets) and twitter username.

Children’s Online Privacy Protection Act Compliance

We are in compliance with the requirements of COPPA (Childrens Online Privacy Protection Act), we do not collect any information from anyone under 13 years of age. Our website, products and services are all directed to people who are at least 13 years old or older.

Updating your personal information

We offer a ‘My details’ page (also known as Dashboard), where you can update your personal information at any time, and change your marketing preferences. You can get to this page from most pages on the site – simply click on the ‘My details’ link at the top of the screen when you are signed in.

Online Privacy Policy Only

This online privacy policy applies only to information collected through our website and not to information collected offline.

Your Consent

By using our site, you consent to our privacy policy.

Changes to our Privacy Policy

If we decide to change our privacy policy, we will post those changes on this page.
Save settings
Cookies settings

You have successfully subscribed to the newsletter

There was an error while trying to send your request. Please try again.

FPGA | Arduino | Matlab | Cours will use the information you provide on this form to be in touch with you and to provide updates and marketing.