ExtruAndWinder/fr

From RepRap
Revision as of 10:31, 16 November 2015 by Blumax (talk | contribs) (Introduction)
Jump to: navigation, search


Introduction

Les machines comme Filabot, Filastruder ou encore Filamaker produise un filament mais n'assure par un filament de diametre constant.

Filastruder propose une seconde machine nommé Filawinder, sont tarif est plutôt abordable. Elle permet d'avoir une certaine constante dans la fabrication du filament.


Apres étude avec TheFredaxe (fas83), du travaille de Hugh Lyman, de Filawinder mais aussi de quelque photo trouvé sur internet de machine induststrielle, je me suis décider à crée une version de cette machine avec des éléments facilement trouvable dans le commerce et communément utilisé dans l'impresion 3D des RepRapeur.


Pourquoi une extrudeuse seul ne remplit pas son role ?
FilaWinder

Le filament est extrudé la gravité attire naturelement le filament vers le sol, sur les 50 premier centimetres pas de probleme, puis la masse tire sur le filament et change le diametres du filament. Quand le filament entre en contact avec le sol, la tension redevient plus faible mais cella crée des irégularité dans le filament.


La technique de Fas83 et de la Filawinder pour compenser ce probleme est d'enroulé le filament en continue pour avoir une certaine "tension" et continuité dans la production du filament.


Un autre probléme sur la machine de Filawinder est la régularité dans le moteur d'extrusion, en effet, il est compossé de plusieur engrenage qui se comprime, de plus lorceque le PID allimente la bande chauffante le moteur réduit sa vitesse.

Construction de la machine

Cette machine est construite aux maximum avec des éléments facilement trouvable dans le commerce et standardisé (Pas de sur-messure).

La machine est constitué de plusieur ensembles que voici :

  1. Extrudeuse de filament
  2. Controleuse de diametre
  3. Moteur de traction
  4. Controleur de tension
  5. Enrouleur de filament

Extrudeuse de filament

Extrudeuse made in Blumax

L'extrudeuse est constitué de plusieur sous-ensembles :

  1. Une motorisation
  2. Le chargement du pellets
  3. L'entrainement
  4. La chauffe
  5. La buse de sortie

BOM

  • Téflon (0,95€ chez LeRoyMerlin réf.60029095)
  • 2 Raccords Té en laiton à visser F20X27 (5,60€ les 2 chez LeRoyMerlin)
  • 1 Mammelons en laiton à visser M20X27 (2,29€ les 2 chez LRM)
  • 2 Manchons en laiton à visser F20X27 (4€ les 2 chez LRM)
  • 4 Bobine + 2 contre écrous en laiton à visser M20X27 (62€ les 4 chez LRM)
  • 2 Mammelons réducteur en laiton à visser M20X27 vers M12X17 (3€ les 2 chez LRM)
  • 1 Coude femelle 20x27mm/femelle 20x27mm (3,95€ les 2 chez LRM)
  • 1 Bouchons en laiton à visser F12X17 (1.39€ chez LRM réf.65816044)
  • Ruban adhésif aluminium (5,1€ chez LRM)
  • 1 meche a simple spirale Lewis de 18mm de diamétre et 450 de long (La spirale Lewis est vraiment importante, la longeur aussi) (42,30€ chez www.sesatools.com réf.12010818450)
  • 1 PID REX-C100 (En lot avec le SSR sur eBay 14€)
  • 1 SSR (En lot avec le PID sur eBay 14€)
  • 1m Thermocouple K-type (Doit supporter jusqu'a 300°C (1,7€ sur eBay)
  • Bande chauffante (Band Heater) AC 220V 110W 30mmx30mm (5,5€ sur Aliexpress)
  • Un planche en bois
  • Quellque vise
  • Equere (imprimable)
  • Isolant (Optionel mais conseiller pour ne pas perdre de la chaleur et avoir une témpérature au mieux stabilisé).
  • Moteur, courroie et engrenage à venire
  • Ecrous de xxx
  • Roulement a bille axiale (5,8€ sur eBay)

Outil :

  • 1 foret fer de 2.8mm
  • 1 foret fer entre 5 et 8mm

Source

ExtruAndWinder.ino

// Je ne sais pas à quoi sert ce truc mais il sert pour le TCL1401
#define FASTADC 1
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

// Décompenter pour debugger
#define DEBUG

#define _Digole_Serial_I2C_  // To tell compiler compile the special communication only
#include <DigoleSerial.h>
#include <Wire.h>
#include <TimerOne.h>

// Fichier avec tous les picrograme de l'interphase graphique.
#include "picto.h"

// Définition des PINs
#define PIN_GUIDE_STEP 9
#define PIN_GUIDE_DIR 8

#define PIN_ENROULEUSE_STEP 13
#define PIN_ENROULEUSE_DIR 12

#define PIN_ELONGATION_STEP 11
#define PIN_ELONGATION_DIR 10

#define PIN_TSL1401_ANALOG 0
#define PIN_TSL1401_SI 3
#define PIN_TSL1401_CLK 2

#define PIN_BOUTON_MOINS 4
#define PIN_BOUTON_PLUS 6
#define PIN_BOUTON_SELECT 5

#define PIN_ENDSTOP_TENSION 7
#define PIN_ENDSTOP_GUIDE 22

#define PIN_ANALOG_LDR_0 2
#define PIN_ANALOG_LDR_1 3
#define PIN_ANALOG_LDR_2 4
#define PIN_ANALOG_LDR_3 5

int ldr_base[4];
int ldr_valeur[4][10];
bool ldr_couper[4];

bool ldrModeAuto = false;

// Définition des parametres
#define PARAM_LCD_ACTUALISATION 500 // Frequence d'actualisation de l'écran

// Seuil de déclanchement du LDR en %
float ldr_seuil = 1.05;

unsigned int elongationDelayEnMicrosManuel = 3000;
unsigned int elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel;
unsigned int elongationDelayEnMicrosAppliquer = elongationDelayEnMicrosManuel;

#define ELONGATION_MIN 800
#define ELONGATION_MAX 6000


unsigned long bascule_vitesse_extra = micros();


unsigned long elongationDernierMillis = micros();
unsigned long elongationNombreDePas = 0;
bool choixElongationActiver = true;

unsigned int enrouleuseDelayEnMicros = 500;
unsigned long enrouleuseDernierMillis = micros();
unsigned long enrouleuseNombreDePas = 0;
bool choixEnrouleuseActiver = false;
bool interneEnrouleuseTendu = false;

unsigned int guideDelayEnMicros = 150;
unsigned long guideDernierMillis = micros();

byte menuPosition = 0;
unsigned long menuMillisSelect = millis();
unsigned long menuMillisPlusMoin = millis();

unsigned int diametreActuelle = 0;
unsigned int diametreActuelleMin = 0;
unsigned int diametreActuelleMax = 128;
unsigned int diametreActuelleAVG = 0;
unsigned long AVGsommeDesDiametre = 0;
unsigned long AVGnombreDeSomme = 0;

unsigned long ecranDerniereActualisation = millis();

// Pas minimum que peux avoir le moteur pour bobiner, ce trouve normalement sur la gauche de la bobine // 47.000
#define GUIDE_PAS_MINI 103000
// Pas maximum que peux avoir le moteur pour bobiner, ce trouve normalement sur la droite de la bobine  // 220.000
#define GUIDE_PAS_MAXI 257000
// Pas que doit avoir le servo pour le premier tour, liér à la position de l'orifice permetant de maintenire le filament // 200.000
#define GUIDE_PAS_DEPART_FIL 247000
// Il est conseiller de réduire d'environ 5mm la taille réel de la bobine // 65mm
#define BOBINE_LARGEUR_MM 65
#define BOBINE_DIAMETRE_INTERIEUR_MM 91
#define BOBINE_DIAMETRE_EXTERIEUR_MM 200

#define DIAMETRE_FILAMENT_SOUHAITER 1.75

// En regardant la machine du coter de l'arrivé du fil en direction de la bobine
// false si le trou qui bloque le filament est plus à gauche
// true si il est le plus à droite
unsigned long guidePositionEnStep = 0;

// (Step par tour d'enrouement est égale à "pas par tour du moteur * démultiplication d'engrenage * résolution du driver (1 = full step, 2 = 1/2 pas, 4 = 1/4 de pas, 8 = 1/8 de pas et 16 = 1/16 de pas)" 200*2.5*4
// L'enregrane actuelle à 21 dents pour la petite roue et 53 pour la grande
#define BOBINE_STEP_TOUR 12800

// DEFINE CALCULER, NE PAS TOUCHER
#define BOBINE_TOUR_PAR_LARGEUR (BOBINE_LARGEUR_MM / DIAMETRE_FILAMENT_SOUHAITER)
#define BOBINE_STEP_PAR_LARGEUR (BOBINE_TOUR_PAR_LARGEUR * BOBINE_STEP_TOUR)
#define GUIDE_LARGEUR_STEP (GUIDE_PAS_MAXI - GUIDE_PAS_MINI)
#define GUIDE_LARGEUR_STEP_UN_BRIN (((GUIDE_LARGEUR_STEP) / BOBINE_LARGEUR_MM) * DIAMETRE_FILAMENT_SOUHAITER)

long guideAllerAuStep = 0;

DigoleSerialDisp ecran(&Wire, '\x27');  // I2C sur Arduino Mega : SDA = 20 et SCL = 21

// Calcule la position du point d'accroche du filament
unsigned long guideDecalagePointDepartEnPasGuide = GUIDE_PAS_MAXI - GUIDE_PAS_DEPART_FIL; // 220.000-200.000 = 20.000
float guideRatioDecalage = ((double)guideDecalagePointDepartEnPasGuide / (GUIDE_LARGEUR_STEP)); // = 20.000 / 173000 = 0.12
unsigned long decalageEnPasBobine = BOBINE_STEP_PAR_LARGEUR * guideRatioDecalage; // 489411,78 * 0.12 = 56579.39 = 56579;

void ldrRecalculerLesBase() {
  ldr_valeur[0][0] = analogRead(PIN_ANALOG_LDR_0);
  ldr_valeur[0][1] = analogRead(PIN_ANALOG_LDR_0);
  ldr_valeur[0][2] = analogRead(PIN_ANALOG_LDR_0);
  ldr_valeur[0][3] = analogRead(PIN_ANALOG_LDR_0);
  ldr_base[0] = (ldr_valeur[0][0] + ldr_valeur[0][1] + ldr_valeur[0][2] + ldr_valeur[0][3]) / 4;
  
  ldr_valeur[1][0] = analogRead(PIN_ANALOG_LDR_1);
  ldr_valeur[1][1] = analogRead(PIN_ANALOG_LDR_1);
  ldr_valeur[1][2] = analogRead(PIN_ANALOG_LDR_1);
  ldr_valeur[1][3] = analogRead(PIN_ANALOG_LDR_1);
  ldr_base[1] = (ldr_valeur[1][0] + ldr_valeur[1][1] + ldr_valeur[1][2] + ldr_valeur[1][3]) / 4;
  
  ldr_valeur[2][0] = analogRead(PIN_ANALOG_LDR_2);
  ldr_valeur[2][1] = analogRead(PIN_ANALOG_LDR_2);
  ldr_valeur[2][2] = analogRead(PIN_ANALOG_LDR_2);
  ldr_valeur[2][3] = analogRead(PIN_ANALOG_LDR_2);
  ldr_base[2] = (ldr_valeur[2][0] + ldr_valeur[2][1] + ldr_valeur[2][2] + ldr_valeur[2][3]) / 4;

  ldr_valeur[3][0] = analogRead(PIN_ANALOG_LDR_3);
  ldr_valeur[3][1] = analogRead(PIN_ANALOG_LDR_3);
  ldr_valeur[3][2] = analogRead(PIN_ANALOG_LDR_3);
  ldr_valeur[3][3] = analogRead(PIN_ANALOG_LDR_3);
  ldr_base[3] = (ldr_valeur[3][0] + ldr_valeur[3][1] + ldr_valeur[3][2] + ldr_valeur[3][3]) / 4;  
}

void setup() {
  #ifdef DEBUG
    Serial.begin(115200);
  #endif

  // "Initialise" les LDR
  pinMode(PIN_ANALOG_LDR_0, INPUT);
  pinMode(PIN_ANALOG_LDR_1, INPUT);
  pinMode(PIN_ANALOG_LDR_2, INPUT);
  pinMode(PIN_ANALOG_LDR_3, INPUT);

  for (byte i = 0; i < 9; i++) {
    ldr_valeur[0][i] = ldr_valeur[0][i+1];
  }
  ldr_valeur[0][9] = analogRead(0);

  for (byte i = 0; i < 9; i++) {
    ldr_valeur[1][i] = ldr_valeur[1][i+1];
  }
  ldr_valeur[1][9] = analogRead(1);

  for (byte i = 0; i < 9; i++) {
    ldr_valeur[2][i] = ldr_valeur[2][i+1];
  }
  ldr_valeur[2][9] = analogRead(2);

  for (byte i = 0; i < 9; i++) {
    ldr_valeur[3][i] = ldr_valeur[3][i+1];
  }
  ldr_valeur[3][9] = analogRead(3);
  
  // Calcule les bases des LDR
  ldrRecalculerLesBase();

  
  // "Initialise" les stepper
  pinMode(PIN_ENROULEUSE_STEP, OUTPUT);
  pinMode(PIN_ENROULEUSE_DIR, OUTPUT);
  digitalWrite(PIN_ENROULEUSE_DIR, HIGH);
  
  pinMode(PIN_ELONGATION_STEP, OUTPUT);
  pinMode(PIN_ELONGATION_DIR, OUTPUT);
  digitalWrite(PIN_ELONGATION_DIR, HIGH);
  
  pinMode(PIN_GUIDE_STEP, OUTPUT);
  pinMode(PIN_GUIDE_DIR, OUTPUT);
  digitalWrite(PIN_GUIDE_DIR, HIGH);
  
  // Définit le ENDSTOP de l'enrouleuse comme un INPUT
  pinMode(PIN_ENDSTOP_TENSION, INPUT);
  
  //Initialise le TSL1401
  pinMode(PIN_TSL1401_SI, OUTPUT);
  pinMode(PIN_TSL1401_CLK, OUTPUT);
  digitalWrite(PIN_TSL1401_SI, LOW);
  digitalWrite(PIN_TSL1401_CLK, LOW);

  // Définit les ports en temps que entré et active le pull-up interne
  pinMode(PIN_BOUTON_MOINS, INPUT);
  digitalWrite(PIN_BOUTON_MOINS, HIGH);
  
  pinMode(PIN_BOUTON_PLUS, INPUT);
  digitalWrite(PIN_BOUTON_PLUS, HIGH);
  
  pinMode(PIN_BOUTON_SELECT, INPUT);
  digitalWrite(PIN_BOUTON_SELECT, HIGH);

  delayMicroseconds(2000);
  // Commence la communication avec le controleur de l'écran
  ecran.begin();
  ecran.disableCursor();  // Désactive le curseur
 // delayMicroseconds(1000);
  ecran.clearScreen();    // Efface l'écran  
  
  ecran.setFont(18);
  ecran.setTextPosAbs(7, 10);
  ecran.print("BluBluStruder");
  
  ecran.setFont(10);
  ecran.setTextPosAbs(4, 64);
  ecran.print("Guidage a 0 en cours");
  
  ecran.setTextPosAbs(20, 25);
  ecran.print("Appuyer sur une");
  ecran.setTextPosAbs(5, 33);
  ecran.print("touche pour calibrer");

  bool entreCalibration = false;
  bool arriverZero = false;
  bool premierRefresh = true;
  do { 
    if(digitalRead(PIN_ENDSTOP_GUIDE) == HIGH) {
      digitalWrite(PIN_GUIDE_STEP, HIGH);
      digitalWrite(PIN_GUIDE_STEP, LOW);
    } else {
      arriverZero = true;  
    }
    
    if(digitalRead(PIN_BOUTON_PLUS) == LOW || digitalRead(PIN_BOUTON_MOINS) == LOW || digitalRead(PIN_BOUTON_SELECT) == LOW) {
      entreCalibration = true;
    }
    
    if(entreCalibration && premierRefresh) {
      ecran.setColor(1);
      ecran.setFont(10);
      ecran.setTextPosAbs(35, 41);
      ecran.print("OK CHEF !");
      
      premierRefresh = false;
    }
   
    delayMicroseconds(100);
  } while(arriverZero == false);
 
  // Active les timers, il sont utiliser pour la callibration
  Timer1.initialize(100);
  Timer1.attachInterrupt(timerIsr);
 
  if(entreCalibration) {
    // Partie pour qualibré
    ecran.clearScreen();
    ecran.setFont(10);
    ecran.setTextPosAbs(0, 8);
    ecran.print("Pas de depart");
    bool continuer = true;
    long serialMillis = millis();
    do {
      // Quitte le reglage si on appuis sur select
      if(digitalRead(PIN_BOUTON_SELECT) == LOW) {
        continuer = false;
      }
      if(digitalRead(PIN_BOUTON_PLUS) == LOW) {
        guideAllerAuStep++;
      }
      if(digitalRead(PIN_BOUTON_MOINS) == LOW) {
        guideAllerAuStep--;
      }
      
      if(serialMillis < millis() - 1000) { 
        ecran.setColor(0);
        ecran.drawBox(0, 18, 128, 11);
        
        ecran.setColor(1);
        ecran.setTextPosAbs(0, 18);
        ecran.print(guideAllerAuStep);
    
        serialMillis = millis();
      }
    } while(continuer);
  }
  
  ecran.clearScreen();
  delayMicroseconds(100);
  
  // Se position au point de depart, le timer1 fait ce quil faut
  guideAllerAuStep = GUIDE_PAS_DEPART_FIL;

  // Affiche tous les elements perseistant
  ecran.clearScreen();
  ecran.drawBitmap(98, 1, 12, 12, pictoEtirement);
  ecran.drawBitmap(98, 28, 12, 12, pictoEnrouleuse);
  ecran.setFont(18);
  ecran.setTextPosAbs(52, 63);
  ecran.print("mm");
  
  ecran.setFont(10);
  ecran.setTextPosAbs(80, 48);
  ecran.print("MAX");
  ecran.setTextPosAbs(80, 56);
  ecran.print("AVG");
  ecran.setTextPosAbs(80, 64);
  ecran.print("MIN");
  ecran.setTextPosAbs(9, 31);
  ecran.print("SEUIL");
  delayMicroseconds(50);
}

void calculPossitionerGuide() {
  long nombreDePasBobineAvecDecallage = enrouleuseNombreDePas + decalageEnPasBobine;
  int nombreDeTourEffectuer = nombreDePasBobineAvecDecallage / BOBINE_STEP_TOUR;
  // nombreDePasBobineAvecDecallage = 96905
  // BOBINE_STEP_PAR_LARGEUR = 489411.78
  // = 0.198
  int nombreDeLargeurBobineEffectuer = nombreDePasBobineAvecDecallage / BOBINE_STEP_PAR_LARGEUR;
  long pasDejaEffectuerSurLargeur = nombreDePasBobineAvecDecallage % (long)(BOBINE_STEP_PAR_LARGEUR);
  float rationTrajetEffectuerParBobine = pasDejaEffectuerSurLargeur / BOBINE_STEP_PAR_LARGEUR;
  long positionDuGuideAPrendre = GUIDE_LARGEUR_STEP * rationTrajetEffectuerParBobine;

  if(nombreDeLargeurBobineEffectuer%2 == 0) {
    guideAllerAuStep = GUIDE_PAS_MAXI - positionDuGuideAPrendre;
  } else {
    guideAllerAuStep = GUIDE_PAS_MINI + positionDuGuideAPrendre;
  }
}

bool ldrCouper(byte numero_pin, byte pin_a_tester) {
  // Décalre l'ensemble des élements du tableau.
  for (byte i = 0; i < 9; i++) {
    ldr_valeur[numero_pin][i] = ldr_valeur[numero_pin][i+1];
  }
  ldr_valeur[numero_pin][9] = analogRead(pin_a_tester);

  // Addition les valeur
  int sommeValeur = 0;
  for (int i = 0; i < 10; i++) {
    sommeValeur += ldr_valeur[numero_pin][i];
  }
  
  // Determine la valeur extreme max
  int max_vals = ldr_valeur[numero_pin][9];
  int min_vals = ldr_valeur[numero_pin][9];
  for (int i = 0; i < 10; i++) {
    max_vals = max(max_vals, ldr_valeur[numero_pin][i]);
    min_vals = min(min_vals, ldr_valeur[numero_pin][i]);
  }

  // En soustrant la valeur max et min, on à une somme de 8 valeurs moins les valeurs extremes.
  sommeValeur = sommeValeur - min_vals - max_vals;
  
  // Divise par 8 (En décalant de 3 bites ?)
  sommeValeur >>= 3;

  // Là on compare un int avec un int * float, sa va allez ?
  
  // Là on compare un int avec un int * float, sa va allez ?
  return ldr_base[numero_pin] > (int)(sommeValeur * ldr_seuil);
}

const int VITESSE_ELONGATION_HAUTE = 3;
const int VITESSE_ELONGATION_MOYENNE = 2;
const int VITESSE_ELONGATION_BASSE = 1;

const int ELONGATION_DELAY_DELTA_FAIBLE = 80; // Therotiquement ne pas toucher
const int ELONGATION_DELAY_DELTA_MOYEN = 300; // Therotiquement ne pas toucher
const int ELONGATION_DELAY_DELTA_FORT = 1500; // Therotiquement ne pas toucher

const int ELONGATION_DELAY_DELTA_EXTRA_FORT_HAUT = 12000;
const int ELONGATION_DELAY_DELTA_EXTRA_FORT_BAS = 2000; // doit etre suppérieur a ELONGATION_DELAY_DELTA_FORT

const int ELONGATION_TEMPO_EXTRA_FORT = 2000; // durée en ms après laquelle on ajoute le DELTA_EXTRA_FORT

void loop() {
  
  ldr_couper[0]  = ldrCouper(0, PIN_ANALOG_LDR_0);
  ldr_couper[1]  = ldrCouper(1, PIN_ANALOG_LDR_1);
  ldr_couper[2]  = ldrCouper(2, PIN_ANALOG_LDR_2);
  ldr_couper[3]  = ldrCouper(3, PIN_ANALOG_LDR_3);
  
  // si on n'est pas en vitesses extrêmes, on se met à la vitesse moyenne et on remet à 0 le timer pour passer en vitesse extra rapide
  if ( elongationDelayEnMicrosAuto > elongationDelayEnMicrosManuel - ELONGATION_DELAY_DELTA_FORT && elongationDelayEnMicrosAuto < elongationDelayEnMicrosManuel + ELONGATION_DELAY_DELTA_FORT ) {
    elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel;
    bascule_vitesse_extra = 0;
  } else {
    // on est en vitesse extrême, vérifions si celà fait assez longtemps pour tenter de passer en vitesse extra
    
    if (millis() >= bascule_vitesse_extra) {
    
      // il est temps de passer en vitesse extra
      if ( elongationDelayEnMicrosAuto < elongationDelayEnMicrosManuel ) {
        elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel - ELONGATION_DELAY_DELTA_EXTRA_FORT_BAS;
      } else {
        elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel + ELONGATION_DELAY_DELTA_EXTRA_FORT_HAUT;
      }
    
    }
    
  }
  
  if(ldr_couper[0]) {
     if (ldr_couper[1]) {
        elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel + ELONGATION_DELAY_DELTA_MOYEN;
     } else {
       elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel + ELONGATION_DELAY_DELTA_FORT;
       if (!bascule_vitesse_extra) {
         bascule_vitesse_extra = millis() + ELONGATION_TEMPO_EXTRA_FORT;
       }
     }
  } else {    
    if(ldr_couper[1]) {
      elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel + ELONGATION_DELAY_DELTA_FAIBLE;
    }
  }
    
  if(ldr_couper[3]) {
    if (ldr_couper[2]) {
      elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel - ELONGATION_DELAY_DELTA_MOYEN;
    } else {       
       elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel - ELONGATION_DELAY_DELTA_FORT;
       if (!bascule_vitesse_extra) {
         bascule_vitesse_extra = millis() + ELONGATION_TEMPO_EXTRA_FORT;
       }
    }
  } else {
    if(ldr_couper[2]) {
      elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel - ELONGATION_DELAY_DELTA_FAIBLE;
    }
  }
  
  if(ldrModeAuto) {
#if defined(DEBUG_ELONGATION)    
    Serial.println("--------");
    Serial.println(ldr_couper[0]);
    Serial.println(ldr_couper[1]);
    Serial.println(ldr_couper[2]);
    Serial.println(ldr_couper[3]);
    
    Serial.println(elongationDelayEnMicrosAuto);
#endif
    
    elongationDelayEnMicrosAppliquer = elongationDelayEnMicrosAuto;
  } else {
    elongationDelayEnMicrosAppliquer = elongationDelayEnMicrosManuel;
  
  }
  calculPossitionerGuide();
//  guideAllerAuStep = 10000;
  
  // Recupere le diametre du filament en valeur "system"
  diametreActuelle = lireCapteur();
  
  diametreActuelleMax = max(diametreActuelleMax, diametreActuelle);
  diametreActuelleMin = min(diametreActuelleMin, diametreActuelle);
  
  AVGsommeDesDiametre += diametreActuelle;
  AVGnombreDeSomme++;
  diametreActuelleAVG = (int)((long)AVGsommeDesDiametre / (long)AVGnombreDeSomme);
  
  // Si le bouton select est pressé
  if(digitalRead(PIN_BOUTON_SELECT) == LOW && (menuMillisSelect < millis() - 250)) {
    menuPosition++;
    if(menuPosition > 6) {
      menuPosition = 0;
    }
    menuMillisSelect = millis();
  }

  // Si le bouton plus est pressé
  if(digitalRead(PIN_BOUTON_PLUS) == LOW && (menuMillisPlusMoin < millis() - 75)) {
    switch(menuPosition) {
      case 0:
        choixElongationActiver = true;
        break;
      case 1:
        elongationDelayEnMicrosManuel = elongationDelayEnMicrosManuel + 50;
        break;
      case 2:
        choixEnrouleuseActiver = 1;
        break;
      case 3:
        diametreActuelleMin = diametreActuelleMax = diametreActuelle;
        AVGsommeDesDiametre = AVGnombreDeSomme = 0;
        break;
      case 4:
        ldrRecalculerLesBase();
        break;  
      case 5:
        ldr_seuil += 0.01;
        break;
      case 6:
        elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel;
        ldrModeAuto = true;
        break;
    }
    menuMillisPlusMoin = millis();
  }

  // Si le bouton moins est pressé
  if(digitalRead(PIN_BOUTON_MOINS) == LOW && (menuMillisPlusMoin < millis() - 75)) {
    switch(menuPosition) {
      case 0:
        choixElongationActiver = false;
        break;
      case 1:
        if(elongationDelayEnMicrosManuel > 0) {
          elongationDelayEnMicrosManuel = elongationDelayEnMicrosManuel - 50;
        }
        break;
      case 2:
        choixEnrouleuseActiver = 0;
        break;
      case 3:
        diametreActuelleMin = diametreActuelleMax = diametreActuelle;
        AVGsommeDesDiametre = AVGnombreDeSomme = 0;
        break;
      case 4:
        ldrRecalculerLesBase();
        break;  
      case 5:
          ldr_seuil -=  0.01;
        break;
      case 6:
        elongationDelayEnMicrosAuto = elongationDelayEnMicrosManuel;
        ldrModeAuto = false;
        break;
    }
    menuMillisPlusMoin = millis();
  }
  
  // Rafréchie l'écran suivant à la fréquence de la constante PARAM_LCD_ACTUALISATION
  if((ecranDerniereActualisation < millis() - PARAM_LCD_ACTUALISATION)) {
    actualiserAffichage();
    ecranDerniereActualisation = millis();
  }
  
  
  if(digitalRead(PIN_ENDSTOP_TENSION) == LOW) {
    interneEnrouleuseTendu = false;
  } else {
    interneEnrouleuseTendu = true; 
  }
}

// Demande au capteur les valeurs et renvoi les pixels les plus claire.
int lireCapteur(void) {
  byte pixel[128]; // Field for measured values <0-255>
  byte blanc = 0;

  // Initilise le capteur
  digitalWrite(PIN_TSL1401_CLK, LOW);
  digitalWrite(PIN_TSL1401_SI, HIGH);
  digitalWrite(PIN_TSL1401_CLK, HIGH);
  digitalWrite(PIN_TSL1401_SI, LOW);
  
  for(int i = 0; i < 128; i++) {
    analogRead(PIN_TSL1401_ANALOG)/4; // 8-bit is enough
    digitalWrite(PIN_TSL1401_CLK, LOW);
    digitalWrite(PIN_TSL1401_CLK, HIGH);
    delayMicroseconds(80);
  }
  
  digitalWrite(PIN_TSL1401_CLK, LOW);
  digitalWrite(PIN_TSL1401_SI, HIGH);
  digitalWrite(PIN_TSL1401_CLK, HIGH);
  digitalWrite(PIN_TSL1401_SI, LOW);

  int maxValue = pixel[0];
  for(int i = 0; i < 128; i++) {
    pixel[i] = analogRead(PIN_TSL1401_ANALOG)/4; // 8-bit is enough
    digitalWrite(PIN_TSL1401_CLK, LOW);
    digitalWrite(PIN_TSL1401_CLK, HIGH);
    maxValue = max(maxValue, pixel[i]);
  }

  maxValue = maxValue * 0.9;
  for(int i = 0; i < 128; i++) {
    if(pixel[i] < maxValue) {
      blanc++;
    }
  }
  
  return blanc;
}

void actualiserAffichage(void) {
  
  // Efface toutes les informations a actualiser
  ecran.setColor(0);
  ecran.drawBox(118, 0, 7, 64); // Curseur de la ligne toutes a droite
  ecran.drawBox(38, 0, 40, 20); // Curseuer et vitesse "d'élongation"
  ecran.drawBox(0, 43, 50, 20); // Diametre actuelle
  ecran.drawBox(98, 41, 19, 23); // Diametre min, max et avg
  ecran.drawBox(12, 0, 22, 22); // Affichage des seuils
  
  ecran.drawBox(0, 0, 7, 33); // Curseur de gauche
  
  ecran.drawBox(42, 22, 35, 18); // Valeur de seuil et tour
//  ecran.drawBox(72, 14, 8, 8); // Curseur mode auto
  
  // Affiche les infos
  ecran.setColor(1);
  
  ecran.setFont(10);
  if(elongationDelayEnMicrosManuel < 10) {
    ecran.setTextPosAbs(77, 7);
  } else {
    if(elongationDelayEnMicrosManuel < 100) {
      ecran.setTextPosAbs(68, 7);
    } else {
      if(elongationDelayEnMicrosManuel < 1000) {
        ecran.setTextPosAbs(59, 7);
      } else {
        ecran.setTextPosAbs(50, 7);
      } 
    } 
  }
  ecran.print(elongationDelayEnMicrosManuel);
  
  
  
  if(elongationDelayEnMicrosAuto < 10) {
    ecran.setTextPosAbs(77, 17);
  } else {
    if(elongationDelayEnMicrosAuto < 100) {
      ecran.setTextPosAbs(68, 17);
    } else {
      if(elongationDelayEnMicrosAuto < 1000) {
        ecran.setTextPosAbs(59, 17);
      } else {
        ecran.setTextPosAbs(50, 17);
      } 
    } 
  }
  ecran.print(elongationDelayEnMicrosAuto);
  
  // Affiche les cases cocher ou decocher suivant leur état
  if(choixElongationActiver) {
    ecran.drawBitmap(111, 4, 6, 6, pictoCocher);
  } else {
    ecran.drawBitmap(111, 4, 6, 6, pictoNonCocher);
  }
  if(choixEnrouleuseActiver) {
    ecran.drawBitmap(111, 31, 6, 6, pictoCocher);
  } else {
    ecran.drawBitmap(111, 31, 6, 6, pictoNonCocher);
  }
  
  ecran.setFont(10);

  
  ecran.setTextPosAbs(87, 21);
  ecran.print("AUTO");
  
  // Affiche le diametre actuelle
  ecran.setFont(120);
  ecran.setTextPosAbs(0, 63);
  ecran.print(diametreActuelle);
  
  ecran.setFont(10);
  ecran.setTextPosAbs(99, 48);
  ecran.print(diametreActuelleMax);
  ecran.setTextPosAbs(99, 56);
  ecran.print(diametreActuelleAVG);
  ecran.setTextPosAbs(99, 64);
  ecran.print(diametreActuelleMin);




  ecran.setFont(6);
  if(ldr_couper[0]) {
    ecran.drawBitmap(9, 0, 6, 6, pictoCocher);
  } else {
    ecran.drawBitmap(9, 0, 6, 6, pictoNonCocher);
  }
  if(ldr_couper[1]) {
    ecran.drawBitmap(9, 6, 6, 6, pictoCocher);
  } else {
    ecran.drawBitmap(9, 6, 6, 6, pictoNonCocher);
  }
  if(ldr_couper[2]) {
    ecran.drawBitmap(9, 11, 6, 6, pictoCocher);
  } else {
    ecran.drawBitmap(9, 11, 6, 6, pictoNonCocher);
  }
  if(ldr_couper[3]) {
    ecran.drawBitmap(9, 17, 6, 6, pictoCocher);
  } else {
    ecran.drawBitmap(9, 17, 6, 6, pictoNonCocher);
  }
  if(ldrModeAuto) {
    ecran.drawBitmap(111, 15, 6, 6, pictoCocher);
  } else {
    ecran.drawBitmap(111, 15, 6, 6, pictoNonCocher);
  }
  
  ecran.setTextPosAbs(16, 5);
  ecran.print(ldr_base[0] - analogRead(PIN_ANALOG_LDR_0));
  ecran.setTextPosAbs(16, 11);
  ecran.print(ldr_base[1] - analogRead(PIN_ANALOG_LDR_1));
  ecran.setTextPosAbs(16, 17);
  ecran.print(ldr_base[2] - analogRead(PIN_ANALOG_LDR_2));
  ecran.setTextPosAbs(16, 23);
  ecran.print(ldr_base[3] - analogRead(PIN_ANALOG_LDR_3));
  
  ecran.setFont(10);
  ecran.setTextPosAbs(42, 31);
  ecran.print(ldr_seuil);

  ecran.setTextPosAbs(42, 39);
  ecran.print(enrouleuseNombreDePas / BOBINE_STEP_TOUR);
  
  switch(menuPosition) {
    case 0:
      ecran.drawBitmap(118, 3, 8, 8, pictoSelection);
      break;
    case 1:
      ecran.drawBitmap(38, 0, 8, 8, pictoSelection);
      break;
    case 2:
      ecran.drawBitmap(118, 29, 8, 8, pictoSelection);
      break;
    case 3:
      ecran.drawBitmap(118, 45, 8, 8, pictoSelection);
      break;
    case 4:
      ecran.drawBitmap(0, 7, 8, 8, pictoSelection);
      break;
    case 5:
      ecran.drawBitmap(0, 26, 8, 8, pictoSelection);
      break;
    case 6:
      ecran.drawBitmap(118, 14, 8, 8, pictoSelection);
      break;
  }
  
  ecran.setTextPosAbs(9, 39);  
  ecran.print("TOURS");
}


// timer1 interrupt function
void timerIsr() {
  unsigned long microsMainteant = micros();
  
  if((microsMainteant - elongationDernierMillis >= elongationDelayEnMicrosAppliquer)) {
    if(choixElongationActiver) {
      PORTB |= B00100000; // = digitalWrite(PIN_ELONGATION_STEP, HIGH);
      PORTB &= B11011111; // = digitalWrite(PIN_ELONGATION_STEP, LOW);
      
      elongationNombreDePas++;
      elongationDernierMillis = microsMainteant;
    }
  }
  
  if((microsMainteant - enrouleuseDernierMillis >= enrouleuseDelayEnMicros)) {
    if(interneEnrouleuseTendu && choixEnrouleuseActiver) {
      PORTB |= B10000000; // = digitalWrite(PIN_ELONGATION_STEP, HIGH);
      PORTB &= B01111111; // = digitalWrite(PIN_ELONGATION_STEP, LOW);
      enrouleuseNombreDePas++;
      enrouleuseDernierMillis = microsMainteant;
    }
  }
  
  if((microsMainteant - guideDernierMillis >= guideDelayEnMicros)) {
    if(guideAllerAuStep >= 0 && guideAllerAuStep != guidePositionEnStep) {
      if(guideAllerAuStep < guidePositionEnStep) {
        PORTH |= B00100000; // = digitalWrite(PIN_ELONGATION_STEP, HIGH);
        guidePositionEnStep--;
      } else if(guideAllerAuStep > guidePositionEnStep) {
        PORTH &= B11011111; // = digitalWrite(PIN_ELONGATION_STEP, LOW);
        guidePositionEnStep++;
      }
      
      PORTH |= B01000000; // = digitalWrite(PIN_ELONGATION_STEP, HIGH);
      PORTH &= B10111111; // = digitalWrite(PIN_ELONGATION_STEP, LOW);
      
      guideDernierMillis = microsMainteant;
    }   
  }
}

picto.h

static const unsigned char PROGMEM pictoEnrouleuse[] = {
  B00011111, B10000000, B00111111, B11000000, B01100110, B01100000, B11000110, B00110000,
  B11000110, B00110000, B10001111, B00010000, B10011111, B10010000, B11111001, B11110000,
  B11110000, B11110000, B01100000, B01100000, B00111001, B11000000, B00011111, B10000000
};

static const unsigned char PROGMEM pictoSelection[] = {
  B00100100, B00100100, B01111110, B11011011, B11011011, B11111111, B11111111, B10100101
};

static const unsigned char PROGMEM pictoNonCocher[] = {
  B00000000, B01111110, B01000010, B01000010, B01000010, B01000010, B01111110, B00000000
};

static const unsigned char PROGMEM pictoCocher[] = {
  B00000000, B01111110, B01111110, B01111110, B01111110, B01111110, B01111110, B00000000
};

static const unsigned char PROGMEM pictoDegre[] = {
  B01100000, B10010000, B10010000, B01100000
};

static const unsigned char PROGMEM pictoChaud [] = {
  B00100010, B00100000, B00010001, B00010000, B00010001, B00010000, B00100010, B00100000,
  B01000100, B01000000, B10001000, B10000000, B10001000, B10000000, B01000100, B01000000,
  B00100010, B00100000, B00000000, B00000000, B11111111, B11110000, B11111111, B11110000
};

static const unsigned char PROGMEM pictoMoteurExtrusion [] = {
  B01111000, B00000000, B00111100, B00010000, B00011100, B00110000, B00001110, B01110000,
  B00001111, B11110000, B00011001, B11100000, B01111001, B10000000, B11111111, B00000000,
  B11100111, B00000000, B11000011, B10000000, B10000011, B11000000, B00000001, B11100000
};

static const unsigned char PROGMEM pictoEtirement [] = {
  B00000110, B00000000, B00001111, B00000000, B00011111, B10000000, B00011111, B10000000,
  B00001111, B00000000, B00000110, B00000000, B00000110, B00000000, B00001111, B00000000,
  B00011111, B10000000, B00011111, B10000000, B00001111, B00000000, B00000110, B00000000
};

Coloration et modification du filament

Colorant alimentaire : La teinte obtenue trop légère, a peine visible dans le filament et invisible une fois imprimé.

Toner d'imprimante : Excellent résultat mais reste translucide

Je vais tester le dioxyde de titane qui à un pouvoir opacifiant ainsi que de la poudre de laiton (risque d’érodé la buse d’impression) mélange de minimum 5g pour 100g.

Pour avoir un effet crais platre, il faut utiliser du mortier ou du pilon, fin dans les deux cas.

Ne pas essayer de mélanger du carbone avec du PLA, ABS, risque d'explosion ! Ne pas essayer le fulmicoton, risque d'explosion, évaluer les risque de la cellulose

Pour aider au dossage du toner dans le but d'avoir une couleur précise utiliser ces cercles chromatique :


ChromaRVB.jpgChroma100Cyan.jpg

Chroma100Magenta.jpgChroma100Jaune.jpg

Remerciment

Je remercie gaston_ et boboss pour leur soutient et aide.

Je remercie fas83 pour le partage de ses connaisances.

Je remerci Viproz pour l'aide au développement sur Arduino

Je remerci gregorio pour ces informations sur la chimie

Je remerci jerome- du chan IRC irc://irc.freenode.net/arduino-fr

Je remercie l'ensemble des membres du chan IRC irc://irc.freenode.net/reprap-fr

Je remercie xxxx pour la correction de cette article