Carte „10(zece) proiecte Internet of Things” în format electronic

Primii zece cumpărători pot beneficia de un preț special: 1.99 EURO utilizând codul promoțional PRIMII10 . Cartea poate fi cumpărată din magazinul 10proiecte iar plata se va face utilizând portalul PayPal. Formatul electronic permite accesul complet la formatul PDF al cărții cu posibilitate de tipărire și extragere de conținut.

 

coperta_v1_mic 

Carte „10(zece) proiecte Internet of Things” în format electronic.

Autor: Radu Pietraru.

240 de pagini cu proiecte despre Internetul obiectelor utilizând plăci de dezvoltare Arduino, Raspberry Pi și ESP8266.

10ProiecteIoT_Cuprins

10ProiecteIoT_PrezentareProiecte

Puteți comanda cartea în format tipărit de pe site-ul Robofun la prețul de 39RON.

Solar Power GPRS Test

Întrebarea la care vom încerca să răspundem în cadrul acestui proiect este: putem construi un sistem IoT cu comunicație GPRS total independent de alimentarea de la rețeaua de energie? Sistemul propus pentru testare este un sistem ce se bazează exclusiv pe alimentare solară. Un astfel de sistem poate fi folosit pentru locații izolate în care nu există disponibile alimentare cu energie electrică și Internet.

Ca soluție de alimentare solară vom utiliza o componentă MPPT: Sunny Buddy – MPPT Solar Charger. Această componentă permite conectarea unei celule solare cu ieșirea între 6V și 20V și încărcarea unui acumulator LiIon sau LiPo cu o singură celulă (3.7V). Curentul maxim de încărcare este de 450mA deci este necesară utilizarea unui acumulator de capacitate minimă 450mAh. În testul nostru vom utiliza o celulă solară de 2.5W / 9V și un acumulator LiPo de 800mAh.  Pentru mai multe detalii despre funcționarea componentei MPTT puteți consulta materialul „Sunny Buddy Solar Charger V13 Hookup Guide”.

Pentru partea de achiziție și raportare IoT vom utiliza placa de dezvoltare Adafruit Feather 32u4 FONA echipată cu un microcontroler ATmega32U4 (la fel ca și placa de dezvoltare Arduino Leonardo) și un controler GSM/2G SIM800 quad-band (850/900/1800/1900MHz).

2

Placa va supraveghea nivelul de încărcare a acumulatorului și va raporta prin Internet (prin intermediul conexiunii GPRS) valorile către serviciul cloud iot.robofun.ro. Placa de dezvoltare se va alimenta de la acumulatorul LiPo conectat la componenta MPPT și va servi ca element de descărcare pentru acesta. Pentru mai multe detalii despre funcționarea și utilizarea plăcii de dezvoltare Adafruit Feather 32U4 FONA puteți consulta materialul „Overview | Adafruit Feather 32u4 FONA | Adafruit Learning System”.

Diagrama de interconectare între componentele sistemului de test este următoarea:

4

Funcționarea plăcii de dezvoltare necesită o antenă GSM uFL. Pentru a minimiza consumul și pentru a putea controla inițializarea sistemului (mai ales în cazul în care acumulatorul sistemului nu este încărcat suficient) pinul KEY al modulului GSM se va deconecta de la masă (necesită tăierea jumperului KEY de pe spatele plăcii) și se va conecta la pinul 0 al plăcii de dezvoltare (firul galben din schema de interconectare).  În acest fel modulul GSM de pe placă nu va mai fi activ continuu ci doar în cazul în care îl vom activa din software. ATENȚIE!!! Această operație conduce la pierderea garanției oferite de producător.

Programul sistemului a fost dezvoltat și testat utilizând Arduino IDE 1.8.5 având instalate extensia Adafruit AVR Boards 1.4.11 și bibliotecile Adafruit FONA Library 1.3.3 și Sleep_n0m1 1.1.1.

#include “Adafruit_FONA.h”

#include <Wire.h>

#define FONA_RX 9

#define FONA_TX 8

#define FONA_RST 4

#define FONA_RI 7

#define FONA_KEY 1

#define FONA_ALARM 13

Definirea constantelor apn, apnusername și apnpassword sunt specifice rețelei de telefonie mobile al SIM-ului GSM utilizat. ATENȚIE!!! Placa de dezvoltare necesită un SIM GSM ce suportă standardul 2G, comunicația GSM nu va funcționa în cazul unui SIM GSM exclusiv 3G/4G.

#define apn “net”

#define apnusername “” 

#define apnpassword “” 

char replybuffer[255];

#include <SoftwareSerial.h>

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

#include <Sleep_n0m1.h>

Sleep sleep;

În cadrul secțiunii setup() se vor inițializa pinii de control utilizați pentru controlul modulului GSM (FONA_KEY este utilizat pentru activarea modulului GSM, FONA_ALARM este conectat la LED-ul de semnalizare al plăcii de dezvoltare și va fi utilizat pentru avertizarea imposibilității inițializării corecte a modulului GSM).

void setup() {

  pinMode(FONA_KEY,OUTPUT);

  digitalWrite(FONA_KEY,HIGH);

  pinMode(FONA_ALARM,OUTPUT);

  digitalWrite(FONA_ALARM,LOW);

}

Secțiunea loop() conține algortimul complet de inițializare și comandă pentru modulul GSM, achiziția nivelului de încărcare a bateriei și transmiterea prin Internet a valorilor către serviciul IoT. Primul pas în execuția algoritmului este intrarea în starea de consum redus pentru o oră – stare obligatorie pentru revenirea sistemului dintr-o stare de oprire completă generată de consumarea completă a acumulatorului (acumulatorul este încărcat suficient pentru inițializarea microcontrolerului ATmega32U4 dar nu și pentru inițializarea modulului GSM).

void loop() {

  sleep.pwrDownMode();

  sleep.sleepDelay(3600000);

Pornirea modulului GSM necesită un impuls de 2 secunde pe pinul FONA_KEY. Sistemul va încerca de 10 ori inițializarea modulului GSM după care va relua perioada de o oră de consum redus.

  digitalWrite(FONA_KEY,LOW);

  digitalWrite(FONA_ALARM,HIGH);

  delay(2000);

  digitalWrite(FONA_KEY,HIGH);

  digitalWrite(FONA_ALARM,LOW);

  delay(2000);

  fonaSerial->begin(4800);

  byte i = 0;

  while (!fona.begin(*fonaSerial)) {

      i++;

      if (i==10) break;

      digitalWrite(FONA_KEY,LOW);

      digitalWrite(FONA_ALARM,HIGH);

      delay(2000);

      digitalWrite(FONA_KEY,HIGH);

      digitalWrite(FONA_ALARM,LOW);

      delay(2000);      

  }

În cazul în care modulul GSM s-a inițializat corect se va încerca deblocarea cartelei SIM pe baza codului PIN (trebuie modificat în program în funcție de codul cartelei folosite). Dacă deblocarea cartelei SIM nu se poate face se va relua perioada de o oră de consum redus – este posibil ca acumulatorul să scadă sub pragul de alimentare corectă a modulului GSM între inițializare și deblocarea cartelei SIM.

if (i!=10) {

    if (! fona.unlockSIM(“0000”) ) {

digitalWrite(FONA_ALARM,HIGH);

delay(1000); i=10; }

    else {  

Programul va aștepta înregistrarea în rețeaua GSM a cartelei SIM a sistemului pentru o perioadă de 100 de secunde.

    uint8_t n = fona.getNetworkStatus();

     i=0;

      while (n!=1) {

        i++;

        if (i==10) break;

        digitalWrite(FONA_ALARM,HIGH);

        delay(5000);

        digitalWrite(FONA_ALARM,LOW);

        delay(5000);

        n = fona.getNetworkStatus();

       }

     }

Postarea valorii de încărcare a acumulatorului se va face doar dacă se va inițializa cu succes partea de comunicații de date (fona.enableGPRS). Măsurarea se va face chiar de modulul GSM. În cadrul programului trebuie personalizate cheile de autentificare (SENSOR_TOKEN1 și SENSOR_TOKEN2) obținute prin înregistrarea gratuită în cadrul serviciului iot.robofun.ro.

if(i!=10) {

      fona.setGPRSNetworkSettings(F(apn),

F(apnusername),F(apnpassword));

      if (fona.enableGPRS(true)) {

      uint16_t vbat;

      uint16_t pbat;

      fona.getBattVoltage(&vbat);

      fona.getBattPercent(&pbat);

      delay(1000);

      uint16_t statuscode;

      int16_t length;

      String SENSOR_TOKEN1=”…”;

      String SENSOR_TOKEN2=”…”;

      String data =

         String(“http”) + “://iot.robofun.ro/api/v1/senzor/” + SENSOR_TOKEN1 +  “/input?value=” + String(vbat, DEC);

      char url[100];

      data.toCharArray(url,data.length()+1);

      fona.HTTP_GET_start(url, &statuscode,

(uint16_t *)&length);

      while (length > 0) {

          while (fona.available()) {

            char c = fona.read();

            length–;

            if (! length) break;

          }

          break;

      } 

      fona.HTTP_GET_end();

      delay(100);

      data = String(“http”) + “://iot.robofun.ro/api/v1/senzor/”) + SENSOR_TOKEN2 + “/input?value=” + String(pbat, DEC);

      data.toCharArray(url,data.length()+1);

      fona.HTTP_GET_start(url, &statuscode,

(uint16_t *)&length);

      while (length > 0) {

          while (fona.available()) {

            char c = fona.read();

            length–;

            if (! length) break;

          }

          break;

      } 

      fona.HTTP_GET_end();

      delay(100);

    }

La final, înainte de reintrarea în modul de consum pentru o oră, se va opri modulul GSM printr-un puls de 2 secunde pe pinul FONA_KEY.

      digitalWrite(FONA_KEY,LOW);

      delay(2000);

      digitalWrite(FONA_KEY,HIGH);

    }

  }

}

Testul a fost efectuat pornind cu acumulatorul sistemului complet consumat (tensiune sub 3.3V). După o zi cu soare, când tensiunea acumulatorului a ajuns la 3.7V, sistemul s-a inițializat complet cu succes și a început să posteze pe serviciul IoT. Acest lucru înseamnă că sistemul își poate reveni dintr-o stare de oprire completă generată de descărcarea acumulatorului (mai multe zile fără lumină solară) fără intervenție umană.

5

În timpul unei zile cu soare acumulatorul câștigă aproximativ 30% din nivelul de încărcare iar procentul de descărcare într-o zi înorată este de circa 15%. Asta înseamnă că o zi cu soare poate fi urmată de două zile înorate fără ca sistemul să descarce acumulatorul. Dacă acumulatorul sistemului este complet încărcat, sistemul poate funcționa fără lumină solară pentru un interval de 6-7 zile

6

Testul efectuat dovește că se poate construi un sistem de raportare IoT GSM/GPRS care să funcționeze în mod autonom pe baza energiei solare fără să fie nevoie de intervenția umană în cazuri speciale de descărcare a acumulatorului.

Solar Power WiFi Test

Implementarea unui proiect cu alimentare solară prezintă mai multe avantaje printre care, bineînțeles, se evidențiază independența de rețeaua electrică tradițională. În același timp un astfel de proiect ridică și multe probleme legate de dimensionarea soluției de alimentare și alegerea componentelor potrivite. Care este dimensiunea panoului solar? Ce soluție de stocare a energiei electrice alegem? Ce soluție de încărcare a acumulatorilor este cea mai potrivită? Acestea sunt câteva dintre întrebările la care vom încerca să răspundem în cadrul acestui proiect. Chiar dacă se poate face o evaluare inițială la nivel teoretic, în cadrul testului nostru vom alege varianta testării efective a soluției alese și evidențierea avantajelor și a punctelor slabe ale acesteia.

Ca soluție de maximizare a eficienței captării energiei solare și de încărcare a acumulatorului vom utiliza o componentă MPPT: Sunny Buddy – MPPT Solar Charger.

2

Această componentă permite conectarea unei celule solare cu ieșirea între 6V și 20V și încărcarea unui acumulator LiIon sau LiPo cu o singură celulă (3.7V). Curentul maxim de încărcare este de 450mA deci este necesară utilizarea unui acumulator de capacitate minimă 450mAh. În testul nostru vom utiliza o celulă solară de 2.5W / 9V și un acumulator LiPo de 800mAh. Pentru a supraveghea procesul de încărcare / descărcare a acumulatorului vom utiliza o placă de dezvoltare Adafruit Feather HUZZAH ce va raporta datele măsurate prin intermediul conexiunii WiFi către serviciul cloud iot.robofun.ro. Placa de dezvoltare se va alimenta de la acumulatorul LiPo conectat la componenta MPPT și va servi ca element de descărcare pentru acesta. Pentru o acuratețe mai bună a măsurătorilor vom utiliza o componentă ce va monitoriza nivelul de încărcare a bateriei: LiPo Fuel Gauge. Componenta de monitorizare se va intercala între ieșirea componentei MPPT și alimentarea plăcii de dezvoltare și va raporta prin intermediul unei magistrale I2C nivelul de încărcare a bateriei.

3

Diagrama de interconectare între componentele sistemului de test este următoarea:

4

Înainte de realizarea montajului și punerea lui în funcțiune este recomandată parcurgerea documentațiilor oficiale ale componentelor utilizate:

Atenție!!! Schema precedentă este schema finală de test. În momentul programării plăcii de dezvoltare trebuie să deconectăm alimentarea plăcii prin intermediul componentei de măsurare (să deconectăm placa de dezvoltare de componenta LiPo Fuel Gauge) și să deconectăm pinul Reset de pinul Wake (GPIO16) – firul galben.

Programul sistemului a fost dezvoltat și testat utilizând Arduino IDE 1.8.5, extensia ESP8266 Community 2.4.0 și biblioteca LiFuelGauge 1.0.

#include <Wire.h>

#include <ESP8266WiFi.h>

#include <ESP8266HTTPClient.h>

#include <LiFuelGauge.h>

În cadrul programului trebuie personalizate datele de conectare la rețeaua WiFi (variabilele ssid[] și pass[]).

char ssid[] = “…”;

char pass[] = “…”;

LiFuelGauge gauge(MAX17043);

Secțiunea setup() se va ocupa cu inițializarea comunicației cu modulul de măsurare a tensiunii din acumulator și cu inițializarea comunicației WiFi.

void setup() {

  gauge.reset();

  WiFi.mode(WIFI_STA);

  WiFi.hostname(“ESP_SolarMeter”);

  WiFi.begin(ssid, pass);

  byte retry = 0;

  while ((WiFi.status() != WL_CONNECTED) && (retry<10)) {

    delay(1000);

    retry++;

    if (retry==10) ESP.restart();

  }

}

Secțiunea loop() conține partea de citire a măsurătorilor efectuate de componenta LiPo Fuel Gauge și de trimiterea acestor măsurători către serviciul IoT. În cadrul programului trebuie personalizate cheile de autentificare (SENZOR_TOKEN1 și SENZOR_TOKEN2) obținute în urma înregistrării gratuite pe iot.robofun.ro. Postarea măsurătorilor se va face la un interval de o oră. Între măsurători sistemul va funcționa în mod de consum redus (deepSleep) pentru a minimiza consumul de energie și maximiza durata de funcționare.

void loop() {

  float batPercentage = gauge.getSOC();

  float batVoltage = gauge.getVoltage(); 

  String SENSOR_TOKEN1=”…”;

  String SENSOR_TOKEN2=”…”;

  HTTPClient http;

  String data =

String(“http://iot.robofun.ro/api/v1/senzor/&#8221;) + SENSOR_TOKEN1 + “/input?value=” + String(batVoltage, DEC);

  http.begin(data);

  int httpCode = http.GET();

  delay(100);

  http.end();

  data = String(“http://iot.robofun.ro/api/v1/senzor/&#8221;) + SENSOR_TOKEN2 + “/input?value=”  + String(batPercentage, DEC);

  http.begin(data);

  httpCode = http.GET();

  delay(100);

  http.end();

  ESP.deepSleep(3600L*1000000L);

}

Testarea sistemului va indica următoarele lucruri esențiale în funcționarea acestuia:

  • Sistemul de încărcare solar este capabil să înmagazineze într-o zi însorită suficientă energie pentru funcționarea sistemului pentru 24 de ore – sistemul poate funcționa autonom într-o perioadă însorită. Mai jos este graficul furnizat de serviciul iot.robofun pentru o succesiune de două zile însorite consecutive. Se poate observa că sistemul recuperează energia consumată peste noapte în timpul zilei.

5

6

  • Peste noapte sistemul pierde circa 30% din capacitatea acumulatorului. Asta înseamnă că sistemul poate funcționa circa trei zile fără reîncărcare (zile fără soare / înorate).

7

  • După epuizarea completă a energiei din acumulator sistemul nu este capabil să repornească singur chiar dacă urmează o zi însorită. Acest lucru este cauzat de curentul mare necesar la inițializarea plăcii de dezvoltare (peste 450mA, peste curentul furnizat de componenta Sunny Buddy). Sistemul nu va reuși să intre în mod de consum redus pentru a lăsa acumulatorul să se reîncarce și va rămâne într-o secvență infinită de inițializare ce va opri procesul de reacumulare a energiei solare.

Testul relevă posibilitatea limitată de funcționare a sistemului propus. Acesta poate funcționa o perioadă nedeterminată de timp în mod autonom atâta timp cât nu apare o succesiune de mai mult de două zile complet înnorate. Curentul mare necesar la inițializarea plăcii de dezvoltare blochează reluarea procesului de reîncărcare solară. Totuși, cu un alt consumator ce necesită un curent mai mic de inițializare, sistemul ar putea funcționa autonom și și-ar putea relua activitatea după o perioadă lungă fără lumină solară.

Optimizarea programelor în mediul Arduino IDE

Optimizarea procesului de compilare

Mediul Arduino IDE utilizează compilatorul GCC. Pe lângă procesul de compilare propriu-zis, mediul de dezvoltare efectuează o serie de operații (pre-procesare) ce permit implementarea funcțiilor specifice Arduino (de exemplu includerea automată a definițiilor din Arduino.h). Pentru detalierea procesului de compilare se poate parcurge materialul „Arduino Build Process”.

Procesul de compilare este efectuat, invizibil pentru programator, la un anumit nivel de optimizare (-Os sau -O2 în funcție de versiunea mediului de dezvoltare). Pentru detalierea nivelurilor de optimizare recomandăm parcurgerea materialului „Using the GNU Compiler Collection (GCC): Optimize Options”. Modificarea nivelului de optimizare la compilarea programului se poate face la nivel de fișiere de configurare a mediului de dezvoltare sau chiar la nivel de program.

Prin introducerea unor directive de compilare putem modica nivelul de optimizare pentru întregul program:

#pragma GCC optimize (“-O0”)

#pragma GCC push_options

void setup() { }

void loop() { }

#pragma GCC pop_options

sau doar pentru o anumită secțiune, funcție sau procedură:

void loop() __attribute__((optimize(“-O0”)));

void loop() { }

 

Optimizarea instrucțiunilor specifice mediului Arduino IDE

Unul din obiectivele principale ale mediului Arduino IDE este înlesnirea accesului programatorului la diversele mecanisme interne ale microcontrolerului. Din aceste motiv s-a efectuat rebotezarea pinilor și tot din același motiv au fost introduse instrucțiuni specifice mediului Arduino IDE de tipul pinMode, digitalRead sau digitalWrite. Din punct de vedere al procesului de învățare și dezvoltare aceste facilități accelerează foarte mult timpul de lucru dar din punctul de vedere al eficienței execuției aduc penalizări destul de mari. Cel mai bun exemplu, prezentat și în materialul „Arduino Is Slow”, este înlocuirea instrucțiunii digitalWrite cu o instrucțiune de modificare a registrului intern ce stochează starea pinului pe care dorim să-l modificăm. Se poate testa diferența dintre timpul de execuție a celor două variante rulând următorul exemplu de program:

void setup()

{

 Serial.begin(9600);

}

void loop()

{

 int initial = 0;

 int final = 0;

 initial = micros();

 for(int i = 0; i < 500; i++)

 {

    digitalWrite(13,HIGH);

    digitalWrite(13,LOW);

 }

 final = micros();

 Serial.print(“Time for digitalWrite(): “);

 Serial.print(final-initial);

 Serial.println(“”);

 initial = micros();

 for(int i = 0; i < 500; i++)

 {

    PORTB |= _BV(PB5);

    PORTB &= ~_BV(PB5);

 

 }

 final = micros();

 Serial.print(“Time for true c command: “);

 Serial.print(final-initial);

 while(1);

}

Programul înlocuiește instrucțiunea digitalWrite cu o scriere în registrul intern al microcontrolerului (pinul 13 este pinul PB5). Rezultatul este destul de convingător:

2

Instrucțiunea digitalWrite nu este singura care poate fi înlocuită în cadrul programelor Arduino pentru a obține performanțe mai bune. O altă instrucțiune ”delicată” ce poate afecta funcționarea unor montaje mai complicate este instrucțiunea shiftOut.  Dacă examinăm fișierul wiring_shift.c din directorul Arduino putem vedea că această funcție se bazează pe instrucțiunea digitalWrite deci poate fi accelerată prin înlocuirea acestei instrucțiuni.

void shiftOut(uint8_t dataPin, uint8_t clockPin,

uint8_t bitOrder, uint8_t val)

{

    uint8_t i;

    for (i = 0; i < 8; i++)  {

         if (bitOrder == LSBFIRST)

             digitalWrite(dataPin, !!(val & (1 << i)));

         else

             digitalWrite(dataPin, !!(val & (1 <<

(7 – i))));

         digitalWrite(clockPin, HIGH);

         digitalWrite(clockPin, LOW);     

    }

}

ATENȚIE!!! Optimizările prezentate conduc la pierderea portabilității programelor între diverse plăci Arduino. Toate indicațiile se aplică direct doar pentru plăcile ce sunt echipate cu un microcontroler ATmega328P (Arduino Uno de exemplu).

Pentru exemplificarea optimizării instrucțiunii shiftOut vom considera următorul montaj bazat pe o placă de dezvoltare Arduino Uno, un registru de deplasare 74HC595 și 8 leduri:

3

Programul propus va implementa un mini joc de lumini ce constă în aprinderea succesivă a câte un led din cele 8. Programul obișnuit (ce utilizează instrucțiunea shiftOut) este:

const int latchPin = 4;

const int clockPin = 3;

const int dataPin = 2;

void setup() {               

  pinMode(latchPin, OUTPUT);

  pinMode(dataPin, OUTPUT); 

  pinMode(clockPin, OUTPUT);

  digitalWrite(latchPin, LOW);

  shiftOut(dataPin, clockPin, MSBFIRST, 0); 

  digitalWrite(latchPin, HIGH);

}

void loop() {

  int afisare = 1;

  while (1) {

   for (int i=0;i<8;i++) {

      digitalWrite(latchPin, LOW);

      shiftOut(dataPin, clockPin, MSBFIRST, afisare << i); 

      digitalWrite(latchPin, HIGH);

      delay(500);

     }

   }

}

Varianta nouă ce nu folosește instrucțiunile shiftOut și digitalWrite este:

void loop() {

  int afisare = 1;

  while (1) {

   for (int i=0;i<8;i++) {

    PORTD |= _BV(PD4);

    for (uint8_t b = 0; b < 8; b++)  {

      if(!!((afisare << i) & (1 << (7 – b)))) PORTD |=

_BV(PD2);

      else PORTD &= ~_BV(PD2);

      PORTD |= _BV(PD3);

      PORTD &= ~_BV(PD3);

    }

    PORTD &= ~_BV(PD4);

    delay(500);

   }

  }

}

Chiar dacă la prima vedere exemplul funcționează la fel, se poate justifica necesitatea modificării codului prin imaginarea situației în care procesul de transmitere serială se repetă de un număr suficient de mare de ori încât produce o întârziere inacceptabilă (de exemplu încascadarea unui număr mare de registre de deplasare).

Utilizarea limbajului de asamblare în Arduino IDE

Ce este ”Inline Assembler”?

Facilitatea de ”Inline Assembler” permite inserarea de cod în limbaj de asamblare în cadrul programelor de C/C++ compilate cu ajutorul GCC (compilatorul utilizat de mediul Arduino IDE). Utilizarea de cod în limbaj de asamblare permite optimizarea unor porțiuni de cod și obținerea unor programe mai mici ca dimensiune (în format binar). Pentru mai multe informații se recomandă consultarea materialului „Inline Assembler Cookbook”.

Inserarea de cod în limbaj de asamblare se face utilizând directiva asm (sau ___asm___) direct în program. De exemplu (instrucțiunea NOP în limbaj de asamblare nu are nici un efect):

asm ( “nop \n”);

Bineînțeles, în cadrul secțiunii de cod în limbaj de asamblare nu vom beneficia de aceleași avantaje și înlesniri ca într-un program obișnuit în limbaj de nivel înalt. Pentru a înțelege mai bine vom reface exemplul clasic din Arduino IDE – programul Blink:

void setup() {

  pinMode(13, OUTPUT);

}

void loop() {

  digitalWrite(13, HIGH);

  delay(1000);

  digitalWrite(13, LOW);  

  delay(1000);     

}

O variantă a acestui program utilizând directiva asm este:

void setup() {

 asm(“sbi  0x04, 0x5 \n”);

}

void loop() {

 asm(“cbi  0x05, 0x5 \n”);  

 delay(1000);                

 asm(“sbi  0x05, 0x5 \n”); 

 delay(1000);           

}

După cum se poate observa instrucțiunile pinMode și digitalWrite, specifice mediului Arduino IDE, au fost înlocuite cu instrucțiuni în limbaj de asamblare: sbi și cbi ce permit setarea sau ștergerea unui bit de la o anumită adresă din memorie. Mai mult decât atâta, nu am mai folosit referința la pinul plăcii Arduino așa cum suntem obișnuiți (pinul 13) ci adrese de memorie la care se află registrele interne de configurare ale pinului (registrul de sens DDRB – adresa 0x04 și registrul de ieșire PORTB – adresa 0x05, în ambele registre am manipulat bitul 5 corespondent pinului PB5 adică pinul 13 al plăcii Arduino). Comparați memoria program ocupată de exemplul original și cel care utilizează directiva asm.

2

Registre interne și echivalarea pinilor între mediul Arduino și arhitectura microcontrolerului ATmega328P

Pentru a ușura lucrul cu pinii I/O mediul Arduino IDE are propria modalitate de identificare a acestora (D0-D13, A0-A5) dar în realitate aceștia sunt organizați în trei porturi a câte 8 pini (PB0-PB7, PC0-PC7, PD0-PD7), echivalența între cele două organizări este reprezentată în diagrama următoare (nu toți pinii sunt prezenți la varianta THT a circuitului ATmega328P):

3

Pentru a putea manipula pinii microcontrolerului (la nivel de limbaj de asamblare) este nevoie să cunoaștem adresele registrelor DDRx (registrul de sens) și PORTx (registrul de ieșire) al portului din care face parte pinul. Pentru mai multe informații despre organizarea internă a registrelor interne este utilă consultarea manualului circuitului ATmega328P.

4 

Exemplu de program: joc de lumini

Presupunem următoarea schemă de interconectare a 8 leduri cu placa de dezvoltare Arduino Uno în mod individual – fiecare led este comandat în mod direct de câte un pin al plăcii de dezvoltare (led 1 – pin 2, led 2 – pin 3…. led 8 – pin 9):

5

Funcționalitatea sistemului va consta în realizarea a două jocuri de lumini. Secțiunea setup a programului va trebui să configureze toți cei opt pini utilizați ca fiind pini de ieșire. Varianta inițială ce utilizează instrucțiunea pinMode este:

void setup() {               

  pinMode(2, OUTPUT);

  pinMode(3, OUTPUT);  

  pinMode(4, OUTPUT); 

  pinMode(5, OUTPUT);   

  pinMode(6, OUTPUT); 

  pinMode(7, OUTPUT); 

  pinMode(8, OUTPUT); 

  pinMode(9, OUTPUT);

  Serial.begin(9600);

}

Prima variantă propusă utilizează instrucțiunea sbi ca și în exemplul precedent (adresa 0x0a este adresa registrului DDRD iar adresa 0x04 adresa registrului DDRB):

asm (

  “sbi 0x0a, 2 \n”

  “sbi 0x0a, 3 \n”

  “sbi 0x0a, 4 \n”

  “sbi 0x0a, 5 \n”

  “sbi 0x0a, 6 \n”

  “sbi 0x0a, 7 \n”

  “sbi 0x04, 0 \n”

  “sbi 0x04, 1 \n”

 );

O variantă mai scurtă este configurarea biților din cele două registre (DDRD și DDRB) simultan utilizând registrul de uz general R26 ca intermediar pentru transmiterea valorii către cele două registre:

asm (

    “ldi r26, 0b11111100 \n”

    “out 0x0a, r26 \n”

    “ldi r26, 0b00000011 \n”

    “out 0x04, r26 \n”

    : : : “r26”

    );

Utilizarea unui registru de uz general trebuie semnalizată compilatorului pentru a nu apărea suprapuneri în utilizarea registrelor – ultima linie din cod, a se vedea și materialul „Arduino Inline Assembly Tutorial #3 (Clobbers)”.

Prima variantă de joc de lumini va aprinde alternativ la un interval de 1 secundă ledurile de rang impar și ledurile de rang par (led 1, led 3, led 5, led 7 – led 2, led 4, led 6, led 8). Secțiunea loop (utilizând cod Arduino) este:

void loop() {

  for (int i=2; i<10; i++) {

      if ((i%2)==0) digitalWrite(i,HIGH);

      else digitalWrite(i,LOW);

   }

   delay(1000); 

   for (int i=2; i<10; i++) {

      if ((i%2)==0) digitalWrite(i,LOW);

      else digitalWrite(i,HIGH);

   }

   delay(1000);

}

Transpunerea în limbaj de asamblare este:

void loop() {

asm (

      “sbi 0x0b,2 \n”

      “cbi 0x0b,3 \n”

      “sbi 0x0b,4 \n”

      “cbi 0x0b,5 \n”     

      “sbi 0x0b,6 \n”

      “cbi 0x0b,7 \n”

      “sbi 0x05,0 \n”

      “cbi 0x05,1 \n”

      “ldi r25, 0x7F \n”

      “wait1: ldi r26, 0xFF \n”

      “wait2: ldi r27, 0xFF \n”

      “wait3: dec r27 \n”

      “nop \n”

      “brne wait3 \n”

      “dec r26 \n”

      “brne wait2 \n”

      “dec r25 \n”

      “brne wait1 \n”     

      “cbi 0x0b,2 \n”

      “sbi 0x0b,3 \n”

      “cbi 0x0b,4 \n”

      “sbi 0x0b,5 \n”     

      “cbi 0x0b,6 \n”

      “sbi 0x0b,7 \n”

      “cbi 0x05,0 \n”

      “sbi 0x05,1 \n”

      “ldi r25, 0x7F \n”

      “wait1b: ldi r26, 0xFF \n”

      “wait2b: ldi r27, 0xFF \n”

      “wait3b: dec r27 \n”

      “nop \n”

      “brne wait3b \n”

      “dec r26 \n”

      “brne wait2b \n”

      “dec r25 \n”

      “brne wait1b \n”

      : : : “r25” , “r26”, “r27”

  ); 

Cea de a doua variantă de joc de lumini va aprinde unul câte unul (pornind de la led-ul 1 până la led-ul 8) toate led-urile și apoi le va stinge în mod similar (în ordine inversă). Operația de aprindere sau stingere a unui led se va efectua la un interval de 500 milisecunde. Secțiunea loop (utilizând cod Arduino) este:

void loop() {

   for (int i=2;i<10;i++) {

     digitalWrite(i,HIGH);

     delay(500); }

   for (int i=9;i>1;i–) {

     digitalWrite(i,LOW);

     delay(500);

   }

  }

Transpunerea în limbaj de asamblare este:

void loop() {

asm (

      “start: sbi 0x0b,2 \n”

      “rcall wait \n”

      “sbi 0x0b,3 \n”

      “rcall wait \n”

      “sbi 0x0b,4 \n”

      “rcall wait \n”

      “sbi 0x0b,5 \n”

      “rcall wait \n”     

      “sbi 0x0b,6 \n”

      “rcall wait \n”

      “sbi 0x0b,7 \n”

      “rcall wait \n”

      “sbi 0x05,0 \n”

      “rcall wait \n”

      “sbi 0x05,1 \n”

      “rcall wait \n”     

      “cbi 0x0b,2 \n”

      “rcall wait \n”

      “cbi 0x0b,3 \n”

      “rcall wait \n”

      “cbi 0x0b,4 \n”

      “rcall wait \n”

      “cbi 0x0b,5 \n”

      “rcall wait \n”     

      “cbi 0x0b,6 \n”

      “rcall wait \n”

      “cbi 0x0b,7 \n”

      “rcall wait \n”

      “cbi 0x05,0 \n”

      “rcall wait \n”

      “cbi 0x05,1 \n”

      “rcall wait \n”     

      “rjmp start \n”

      “wait: ldi r25, 0x3F \n”

      “wait12: ldi r26, 0xFF \n”

      “wait22: ldi r27, 0xFF \n”

      “wait32: dec r27 \n”

      “nop \n”

      “brne wait32 \n”

      “dec r26 \n”

      “brne wait22 \n”

      “dec r25 \n”

      “brne wait12 \n”

      “ret \n”

      : : : “r25” , “r26”, “r27”

  );

}

Ambele jocuri de lumini utilizează instrucțiunile sbi și cbi pentru manipularea pinilor I/0 (pentru o listă completă a instrucțiunilor în limbaj de asamblare se recomandă parcurgerea materialului „AVR Instruction Set Manual”). Funcția de temporizare delay din mediul Arduino IDE este înlocuită cu o succesiune de bucle ce realizează o întârziere aproximativă (în a doua variantă această succesiune este implementată ca o subrutină).

Toilet Time

Ignorat sau râvnit, tihnit sau zbuciumat, relaxare sau chiar plăcut timp de lectură… putem descrie în multe moduri timpul petrecut la toaletă dar știm de fapt care este acest timp? În cadrul proiectului de față vom prezenta realizarea unui sistem ce permite măsurarea timpului petrecut la toaletă. Chiar dacă poate părea puțin bizară tematica propusă vă asigurăm că mulți pasionați de sisteme electronice programabile s-au gândit cel puțin o dată la un sistem care să accesorizeze toaleta proprie; câteva exemple de astfel de proiecte:

Sistemul propus de noi se bazează pe o placă de dezvoltare Adafruit Feather HUZZAH echipată cu microprocesorul WiFi ESP8266. Conectivitatea WiFi va permite consultarea timpului total petrecut la toaletă prin intermediul oricărui dispozitiv inteligent cu conectivitate de rețea (tabletă, telefon mobil). În plus, specific tuturor plăcilor din familia Feather, placa de dezvoltare se poate alimenta de la un acumulator LiPo de 3.7V permițând crearea simplă a unui sistem independent de alimentarea USB. Detectarea ocupării toaletei se va face cu ajutorul unui buton brick ce se va poziționa sub colacul toaletei. Greutatea colacului nu este suficientă pentru a apăsa butonul, butonul se va apăsa doar dacă toaleta este ocupată. Bineînțeles, se poate înlocui componenta buton brick cu un senzor de apăsare brick dacă se dorește perfecționarea dedectării ocupării toaletei sau dacă se dorește realizarea unui sistem cu mai mulți ”utilizatori”.

Schema de interconectare dintre placa de dezvoltare și brick-ul buton este următoarea:

2

Brick-ul se va alimenta la 3.3V iar ieșirea se va conecta la pinul GPIO12 al plăcii de dezvoltare.

Programul a fost dezvoltat și testat utilizând Arduino IDE 1.8.5 având instalată extensia ESP8266 Community 2.3.0. În cadrul programului trebuie personalizate datele de conectare WiFi (variabilele ssid și password).

#include <ESP8266WiFi.h>

#include <WiFiClient.h>

#include <ESP8266WebServer.h>

#include <EEPROM.h>

const char *ssid = “…”;

const char *password = “…”;

ESP8266WebServer server (80);

#define pinButton 12

Timpul total de utilizarea a toaletei este stocat în variabila globală toilettime ca număr de secunde. Consultarea timpului total se poate face accesând adresa IP a sistemului (oferită prin DHCP de către AP-ul WiFi) dintr-un client web (browser web). Procedura handleRoot() este responsabilă de construirea paginii HTML trimisă către clientul web. Timpul total se va afișa în format HH:MM:SS. Programul poate fi îmbunătățit în această privință pentru a afișa durate mai mari de timp (sub formă de zile, săptămâni, ani).

3

char temp[600];

unsigned long toilettime;

void handleRoot() {

int sec = toilettime % 60;

int min = (toilettime / 60) % 60;

int hr = toilettime / 3600;

snprintf ( temp, 600,”%02d:%02d:%02d”, hr, min, sec);

String page = “<html>\

<head>\

<meta http-equiv=’refresh’ content=’10’/>\

<title>Toillet Time</title>\

<style>\

body { background-color: #cccccc; font-family:

Arial, Helvetica, Sans-Serif; Color: #000088; }\

</style>\

</head>\

<body>\

<h1>Toilet Time</h1>\

<p><b>Your total time is:</b> ” + String(temp) + “

</p>\

</body>\

</html>”;

page.toCharArray(temp,page.length()+1);

server.send ( 200, “text/html”, temp );

}

Variabila ocupat are semnificația de toaletă ocupată. Când variabila ocupat are valoare true sistemul va contoriza timpul scurs și îl va adăuga la variabila toilettime. Conținutul variabilei toilettime se va salva în memoria flash a plăcii de dezvoltare la fiecare trecere din true în false a variabilei ocupat – acest lucru va asigura păstrarea timpului total și după un reset al plăcii de dezvoltare. Pentru operațiile cu memoria flash programul utilizează biblioteca Arduino IDE EEPROM. Placa de dezvoltare nu are memorie EEPROM, versiunea pentru ESP8266 a bibliotecii EEPROM utilizează aceleași funcții și metode ca la plăcile Arduino dar se folosește de memoria program flash. În cadrul secțiunii setup(), la fiecare nouă inițializare a programului, variabila toilettime se inițializează din memoria non-volatilă program.

boolean ocupat;

void setup() {

pinMode(pinButton, INPUT);

EEPROM.begin(512);

toilettime = 0;

toilettime += (long)EEPROM.read(0)<<24;

toilettime += (long)EEPROM.read(1)<<16;

toilettime += (long)EEPROM.read(2)<<8;

toilettime += (long)EEPROM.read(3);

WiFi.begin ( ssid, password );

while ( WiFi.status() != WL_CONNECTED ) {

delay ( 500 );

}

server.on ( “/”, handleRoot );

server.begin();

ocupat = false;

}

Variabilele start și stopp memorează momentele trecerii variabilei ocupat din false în true (așezarea pe toaletă) și din true în false (ridicarea de pe toaletă). În momentul adunării timpului scurs la variabila globală toilettime, conținutul acesteia este salvată și în memoria flash.

unsigned long start, stopp;

void loop() {

if ((!ocupat) && (digitalRead(pinButton)==1)) {

start = millis();

ocupat = true;

}

if (ocupat && (digitalRead(pinButton)==0)) {

stopp = millis();

ocupat = false;

toilettime += (stopp – start)/1000;

byte temp;

temp = (toilettime>>24) & 0xFF;

EEPROM.write(0, temp);

temp = (toilettime>>16) & 0xFF;

EEPROM.write(1, temp);

temp = (toilettime>>8) & 0xFF;

EEPROM.write(2, temp);

temp = toilettime & 0xFF;

EEPROM.write(3, temp);

EEPROM.commit();

}

server.handleClient();

}

În cazul în care vă plictisiți testând sistemul vă recomandăm aplicația mobilă Android Toilet Time – Mini-games for the bathroom.

Imprimanta Robofun 20-20-20 – HOW TO

Inainte de a incepe acest articol, te rog sa citesti cu mare atentie cele de mai jos.

Imprimanta 3D se alimenteaza in priza de 220 V. NICIODATA si sub nici un motiv nu desface carcasa imprimantei, nu introduce obiecte metalice in zona sursei de alimentare. Daca observi probleme in zona sursei sau a firelor de conexiune la priza, deconecteaza imediat imprimanta de sub tensiune si returneaz-o pentru reparatii. PERICOL DE ELECTROCUTARE !

De asemenea, nu lasa niciodata imprimanta 3D sub tensiune (conectata la priza) fara supraveghere. 

 

Pasii pentru a pune in functiune o imprimanta 3D Robofun  sunt cei de mai jos :

  1. descarca si instaleaza Cura (software-ul care proceseaza modelul 3D si il face usor de inteles pentru imprimanta)
  2. descarca si instaleaza Repetier (software-ul care gestioneaza procesul de printare)
  3. pune imprimanta sub tensiune si testeaza ca totul este OK din punct de vedere mecanic si software
  4. calibreaza distanta de start pe axa Z, daca este cazul
  5. calibreaza orizontalitatea bed-ul, daca este cazul
  6. primul print

 

Cand vei termina filamentul, va fi necesar sa il schimbi, conform instructiunilor de mai jos.

1. Instalare Cura

Cura este acel software care analizeaza obiectul 3D (pe care il ai in format STL) si genereaza un cod sursa pe care imprimanta il intelege (in format gcode).

Mergi la adresa web https://ultimaker.com/en/products/cura-software/list si descarca “Version: 2.3.1” (pe 32 de biti sau pe 64 de biti, in functie de ce arhitectura ai la PC; daca esti in dubiu, alege 32 de biti, va functiona oricum). Sigur ca poti alege si versiuni mai noi, insa tutorialul de mai jos este creat pentru Cura 2.3.1 Am ales aceasta versiune pentru ca este ultima care mai suporta versiune de 32 de biti.

Deschide fiecare grup de setari din partea dreapta si asigura-te ca totul este ca mai jos.

Optiunile “Retraction Distance” si “Retraction Speed” probabil ca nu sunt vizibile by default. Este necesar sa accesezi optiunea “Configure Settings Vizibility” din meniul “Settings” si sa le activezi (fa o cautare dupa “retract” – introdu acest text in campul “Filter” si va fi simplu).

 

 

2. Instalare Repetier

Repetier este acel software care se ocupa efectiv de procesul de printare. Rolul lui este de a trimite progresiv codul gcode la imprimanta si a monitoriza parametri de printare.

Descarca “Repetier Host Windows 2.0.5” de la adresa – https://www.repetier.com/download-now/ . Sigur, poti descarca si o versiune mai noua daca vrei, insa tutorialul de mai jos este pentru versiunea 2.0.5

 

3. Teste preliminare imprimanta

A. conectare cablu USB

Folosind cablul USB primit o data cu imprimanta, conecteaza imprimanta la PC, ca in poza de mai jos.

Nu toate cablurile USB sunt la fel de bune, asa ca pentru inceput, te rog sa folosesti cablul primit o data cu imprimanta. Mai tarziu, dupa ce printezi cateva zile, il poti schimba daca vrei, insa daca apar orice fel de probleme, intoarce-te la cablul USB original.Viteza de transfer este destul de mare, asa ca ai nevoie de un cablu care sa o poata suporta.

 

B. drivere si port USB

Ar trebui ca PC-ul sa vada automat imprimanta si sa creeze un nou port serial pentru comunicarea cu aceasta.

Deschide Control Panel, apoi Device Manager, si verifica sectiunea “Ports”. Ar trebui sa ai o inregistrare similara cu cea de mai jos. Probabil ca la tine numarul portului va fi mult mai mic (gen COM4, sau COM5).

Daca nu vezi o astfel de inregistrare in Device Manager, inseamna ca driver-ele nu sunt corect instalate. Ne poti contacta la adresa de email contact [at] robofun [dot] ro si te vom ajuta cu placere sa rezolvi problema.

C. conectare Repetier

Conecteaza imprimanta la 220 V, in priza. Inca o data, repet avertismentul de la inceput. NU deschide carcasa imprimantei si NU introduce obiecte metalice in zona sursei. Pericol de electrocutare !

Deschide programul “Repetier-Host”, instalat la pasul precedent.

Din meniul “Config”, alege optiunea “Printer Settings”. Selecteaza portul pe care l-ai vazut mai devreme in Device Manager, apoi selecteaza o viteza de transfer (Baud Rate) de 115200, si apasa OK.

Apasa butonul “Connect”, din stanga sus. Ar trebui ca eticheta butonului sa se schimbe in “Disconnect”, iar in partea de jos a ecranului sa vezi o serie de mesaje primite de la imprimanta, ca mai jos.

Daca nu vezi aceste mesaj, inseamna ca exista o problema si nu vei putea printa. Verifica inca o data in Device Manager numarul portului serial COM, si asigura-te ca este corect introdus in Printer Settings. Asigura-te ca viteza este de 115200. Daca nu reusesti, ne poti contacta la adresa de email contact [at] robofun [dot] ro si te vom ajuta cu placere sa rezolvi problema.

D. teste miscare din Repetier

Deschide tab-ul “Manual Control” (dreapta sus). Aceasta sectiune iti permite sa iti controlezi imprimanta manual, pentru teste.

Apasa “HOME X”. Ar trebui sa vezi ca axa X (hotend-ul) se misca. Apasa butonul “HOME Y”. Ar trebui sa vezi ca axa Y (bed-ul) se misca.

Daca nu se intampla asta, verifica daca imprimanta este in priza, si daca in priza chiar ai curent 🙂

 

 

E. teste incalzire din Repetier

In zona inferioara a tab-ul “Manual Control” vezi temperaturile curente ale bed-ului si ale extruderului. Ar trebui sa vezi temperatura ambianta in acest moment. Apasa pe icon-ul “INCALZIRE BED”, apoi apasa pe icon-ul “INCALZIRE HOTEND”, astfel incat sa nu mai fie taiate cu linie rosie. Vei observa ca si bed-ul si hotend-ul incep sa se incalzeasca.

 

F. test extrudare din Repetier

Dupa ce hotend-ul a atins 200 de grade (verifici temperatura afisata), apasa butonul “AVANS FILAMENT”. In functie de unde anume apesi, vei scoate 10 mm, 50 de mm sau 100 de mm de filament. Recomand sa apesi astfel incat sa scoti 50 de mm de filament. Motorul montat in partea de sus, cel care actioneaza extruder-ul va incepe sa se miste si vei observa cum filamentul iese prin hotend (este “extrudat”).

Miscarea filamentului trebuie sa fie continua, si la fel si curgerea filamentului topit prin hotend.

 

4. Calibrare pe axa Z

Este foarte important ca distanta dintre bed si hotend sa fie exact cat trebuie atunci cand incepe procesul de printare. Daca este prea mare, filamentul nu va adera la bed. Daca este prea mica, filamentul nu va avea loc sa iasa din cauza bed-ul. Acest lucru se regleaza din elementul din stanga.

Rolul lui este de a lovi in butonul mic, de culoare rosie, si de a semnaliza astfel pozitia de zero pe axa verticala. Este prins pe surub, astfel incat daca il rotesti spre dreapta, surubul se insurubeaza in prindere, iar elementul de reglaj se misca in sus. Daca il rotesti spre stanga, surubul se desurubeaza, iar elementul de reglaj de misca in jos. Atunci cand se misca in sus, el va lovi mai tarziu butonul, astfel incat distanta de start va fi mai mica. Cand se misca in jos, va lovi mai devreme butonul, deci distanta de start va fi mai mare.

Misca cu mana hotend-ul si bed-ul astfel incat hotend-ul sa se afle relativ in centrul bed-ul. Pune o coala de hartie obisnuita pe bed si apasa butonul “HOME Z”. Vei vedea ca hotend-ul incepe sa coboare. In momentul in care elementul de reglaj din poza de mai sus atinge butonul, hotend-ul se va opri. Foaia de hartie este prinsa intre hotend si bed in acest moment. Incearca sa o misti. Ar trebui sa o poti misca, dar cu un pic de rezistenta.

Daca este foarte bine fixata si nu o poti misca, inseamna ca distanta este prea mica. Apasa pe butonul “Z UP” ca sa misti axa Z in sus cu 10 mm, apoi roteste elementul de reglaj spre stanga, ca sa il deplasezi in jos (astfel incat sa loveasca mai devreme butonul) si apasa iar pe butonul “HOME Z”.

Daca foaia de hartie se misca liber, inseamna ca distanta este prea mare. Apasa pe butonul “Z UP” ca sa misti axa Z in sus cu 10 mm, apoi roteste elementul de reglaj spre dreapta, ca sa il deplasezi in sus (astfel incat sa loveasca mai tarziu butonul), si apasa iar pe butonul “HOME Z”.

Repeta pasii pana cand foaia de hartie se misca, dar cu un pic de rezistenta.

 

 

5. Calibrarea orizontalitatii bed-ului

Misca cu mana bed-ul si hotend-ul astfel incat sa duci hotend-ul in fiecare dintre cele patru colturi ale bed-ului, si repeta teste cu foaia de hartie de mai sus pentru fiecare colt. Ca diferenta, distanta o reglezi de data aceasta NU din elementul mobil folosit la pasul 4, ci direct din piulita de prindere a bed-ului din acel colt.

Bed-ul este prin pe arcuri, asa ca prin rasucirea piulitei de prindere poti ridica si cobori fiecare colt. Continua pana cand poti misca foaia de hartie relativ liber in fiecare colt.

 

6. Primul print

Descarca obiectul STL de aici – https://www.robofun.ro/docs/x-carriage.stl

Deschide Cura (instalat la unul dintre pasii anteriori)

Din meniul “File”, alege “Open File”. Selecteaza fisierul STL descarcat.

Apasa butonul “Save to File” (dreapta jos). Salveaza fisierul gcode unde vrei tu.

Deschide Repetier. Incarca fisierul gcode (butonul “Load”). Atentie mare la acest pas, incarca fisierul cu extensia .gcode si NU cel cu extensia .STL !

Apasa butonul “Start Print”.

Dupa ce hotend-ul se incalzeste la 210 grade, imprimanta va incepe sa printeze.

 

 

 

SCHIMBARE FILAMENT

Dupa primul print, urmeaza al doilea, apoi al treilea, si la un moment dat se termina filamentul. Operatiunea de schimbare este relativ simpla, cat timp urmezi exact pasii de mai jos.

  1. incalzesti hotendul la 210 grade (si astepti sa ajunga la temperatura asta).
  2. extrudezi circa 5-10 cm de filament (rotesti roata extruder-ului – manual sau din Repetier in sensul in care filamentul iese topit prin hotend). Acest pas este extrem de important. Dupa printul anterior, filamentul lichid s-a solidificat in hotend, in forma hotend-ului. Daca nu faci acest pas, atunci cand vei incerca sa il scoti, se va rupe. Scotandu-l prin hotend in forma lichida, te asiguri ca filamentul care a fost topit la pasul anterior si apoi solidificat este complet eliminat sub forma lichida.
  3. scoti complet filamentul din imprimanta (rotesti roata extruder-ului – manual sau din Repetier in sensul in care filamentul iese din imprimanta)
  4. indrepti noul filamentul la capat
  5. introduci noul filament si il cobori prin tubul de teflon pana la hotend, invartind roata extruderului.

Inainte sa apuci de treaba, urmareste neaparat si filmele de mai jos (cu sunet !)

 

 

 

 

 

 

Troubleshooting

1. PROBLEMA :

Obiectul nu se lipeste pe bed, sau se lipeste la inceput, dar in timpul printarii se dezlipeste

REZOLVARE:

Cel mai probabil distanta de start pe Z nu este cea corecta. Vezi mai sus sectiunea “4. Calibrare pe axa Z”. Daca este OK distanta, este posibil ca adezivul depus pe bed sa se fi uscat prea tare. Poti depune un nou strat de adeziv pe bed (vezi link ca sa intelegi despre ce adeziv vorbesc) . Poti deasemenea spala sticla (dupa ce o scoti din cele patru clame), o usuci, si abia apoi aplici adezivul.

2. PROBLEMA :

Avand hotend-ul incalzit la mai mult de 200 de grade, filamentul refuza sa curga.

REZOLVARE:

Cel mai probabil nu ai calibrat corect distanta de start pe axa Z, si curgerea filamentului a fost blocata de sticla de pe bed, datorita distantei extrem de mici intre hotend si bed (vezi filmele de la “4. Calibrare pe axa Z”).

Filamentul a fost fortat mai mult timp de catre surubul de transport, curgerea normala a fost blocata, si astfel filamentul a fost tocat de catre surub. Va trebui sa incerci sa il scoti si sa il pui din nou. Vezi filmul de mai jos.