Se afișează postările cu eticheta electronica. Afișați toate postările
Se afișează postările cu eticheta electronica. Afișați toate postările

joi, 15 august 2019

Mini proiectul de vineri (15) - Activare laser folosind un circuit cu optocuplor

Descriere proiect:
Azi am la teste un modul laser de 5500mW, care o sa-l folosesc mai departe la un alt proiect CNC laser engraver. Tin sa va avertizez ca acest laser este foarte periculos pentru ochi, si am purtat tot timpul ochelarii protectori. Circuitul de activare contine doua parti:

  1. Circuitul de activare de 5V de la Arduino
  2. Circuitul de stabilizare de la 12V la 5V pentru activarea laserului.

Documentatie proiect:

Componente:

Schema electronica/sistem:
Circuitul de mai jos a fost conceput în colaborare cu colegul meu Mihai Taloș:
O poza in care am surprins momentul in care laserul este activat alternativ de un semnal ON-OFF (gen PWM) primit de la Arduino:
Semnalul PWM masurat pe osciloscop:
Conectorul din stanga vine de la arduino , iar cel din dreapta este conectat la o sursa de 12 V si la laser:
Conectarea laserului:

Cod de test: Codul de mai jos este de fapt implementarea pentru aprinderea alternativa a unui LED, si care se potriveste excelent pentru testul meu:
// constants won't change. Used here to set a pin number:
const int ledPin =  13;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 500;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}
O zi bună tuturor!

marți, 13 august 2019

Mini proiectul de vineri (14) - Senzor miscare tip radar (doppler)

Descriere proiect:
Azi am la teste un senzorul radar cu microunde Doppler cu inducție automată de înaltă sensibilitate RCWL-0516, care poate fi utilizat cu ușurință în combinație cu microcontrolerul preferat, calculatoarele cu o singură placă sau ca senzor de detecție autonom. Modulul RCWL emite frecvența de microunde TX / RX de 3.2 Ghz. Componenta principală a acestui modul este tranzistorul MMBR941M, un tranzistor NPN de înaltă frecvență, care este prezent in configurația Ocillator Colpitt .
Un exemplu de circuit oscilator Colpitt:

Funcția principală a unui radar Doppler este de a procesa semnalul RX si semnalul transmis TX pentru a determina care este diferența de frecventa.

Acest modul senzor a fost conceput ca o alternativă la senzorii de mișcare PIR obișnuiți, utilizați pe scară largă în alarme antiefracție și lumini de securitate. La fel ca senzorul PIR, acest senzor detectează, de asemenea, doar mișcări în domeniul său de detecție. Dar în loc să sesizeze radiația corpului negru de la o persoană în mișcare, acest senzor folosește o tehnică „radar Doppler cu microunde” pentru a detecta obiecte în mișcare. Are o rază de sensibilitate de ~ 7 metri. Când este declanșat, pinul său de ieșire la nivelul TTL (OUT) va trece de la LOW (0 V) la HIGH (3,3 V) pentru un timp fin (2 până la 3 s) înainte de a reveni la starea de ralanti (LOW).

Documentatie proiect:
Caracteristici :
Tensiune de alimentare: 4–28 VCC (testat cu 5 V la laboratorul meu)
Frecvența de operare: ~ 3,2 GHz (observată de mine în laboratorul meu)
Putere de transmisie: 20 mW (tipic) / 30 mW (max)
Distanța de detectare: 5–7 m (> 3 m măsurată la laboratorul meu)


Pinouts: CDS — Sensor disable input (low = disable)
VIN — 4- to 28-V DC supply input
OUT — HIGH (3.3 V) motion detected/LOW (0 V) idle
GND — Ground/0 V
3V3 — Regulated DC output (100 mA max)
Detalii RCWL-0516

Componente:
Data sheet RCWL-0516

Schema electronica/sistem:

Cod de test:
static bool value = -1;
boolsense;
const int8_t Output = 13;
const int8_t sensor = 2;


void setup(){
Serial.begin(9600);
Serial.println("Arduino MCU Started......");
digitalWrite(Output,0);

pinMode(Output, OUTPUT);
pinMode(sensor, INPUT);
}

void loop(){  
sense = digitalRead(sensor);
if (sense != value){
  Serial.println("Raw Value :");
  Serial.print(sensor);
  Serial.println(sense ? "+HIGH" : "-LOW");
  digitalWrite(Output, sense);
  value = sense;
  }
  delay(20);
}
O zi buna tuturor !

luni, 12 august 2019

Mini proiectul de vineri (13) - FC-75 Mini incarcator pentru baterie litiu ion

Descriere proiect:
Azi am la teste o placă de încărcare simplă și ieftină a bateriei de litiu ion. Utilizează un micro USB pentru conectarea plăcii la orice computer sau „adaptor de perete USB”. Funcționează cu metoda de încărcare liniară. Oferă curent de încărcare de 1000mA în mod implicit, dar este reglabilă de la 50mA la 1000mA prin lipirea unui rezistor. Rezistența implicită încorporată pe placă este de 1,2 K Ohm.Este recomandat ca atunci când încărcați o baterie, curentul (în mA) oferit pe iesire să fie de 37-40% din capacitatea bateriei (în mAh). De exemplu, dacă încărcați o baterie cu o capacitate de 1000mAh, ar trebui să ajustați rezistența într-un mod în care curentul oferit să fie de aproximativ 370mA-400mA.

Alte detalii:
Numele: 5V Mini USB 1A Placă de încărcare a bateriei de litiu
Modul de încărcare: încărcare liniară
Curent: 1A reglabil
Precizia încărcării: 1,5%
Tensiune de intrare: 4.5V-5.5V
Tensiune de încărcare completă: 4.2V
Temperatura de lucru: de la -10 ℃ la + 85 ℃
Polaritate inversă: NU
Indicator LED: Roșu se încarcă și VERDE (plăcuța mea are LED albastru) este complet încărcat
Interfață de intrare: Micro USB


Utilizați următorul tabel de rezistențe pentru a lipi rezistorul corect pentru a obține curentul necesar: RPROG (k) - IBAT (mA) 30 -50
20 -70
5 -250
4 -300
3 -400
2 -580
1.66 -690
1,5 -780
1.33 -900
1.2 -1000


Componente:
FC-75 bazat pe chipul TP4056

Schema electronica/sistem:

Se poate folosi in doua moduri distincte, se pot lipi firele de sursa de alimentare sau se poate conecta direct cablul de micro USB:
Montaj tipic pentru chipul TP4056:

O zi buna tuturor !

vineri, 8 martie 2019

Mini proiectul de vineri (12) - Servo motor

Descriere proiect:
Azi am la teste un servomotor simplu cu trei pini VCC, GND si pinul de comanda. Am folosit pinul 2 de pe placa Arduino, care are și PWM. Pentru acest servomotor a trebui sa-i conectez o sursa de tensiune de minim 6V pentru că motorașul consumă mai mult curent decât curentul furnizat de placa Arduino. GND-ul l-am conectat comun pentru a avea aceeași masă pentru Arduino și servomotor. În circuit am folosit un acumulator de 7.2V si 1600 mAh, o placă distribuitor cu întrerupător de la o dronă mai veche. Servomotorul s-a încălzit un pic și sincer nu știu dacă e normal sau este acumulatorul un pic prea puternic. Funcționează destul de bine, și o să încerc să mai conectez încă un servomotor să observ dacă accumulatorul poate să furnizeze suficient curent pentru mai multe servomotoare.

Documentatie proiect:


Componente:


Schema electronica/sistem:

Cod de test: L-am programat să se învârtă 180 grade într-un sens și invers. Merge brici :D
//Servos
#include "servo.h"
Servo myservo;  // create servo object to control a servo 
int pos = 0;    // variable to store the servo position
void setup() {
  Serial.begin(9600);

  myservo.attach(2);  //the pin for the servo control

  Serial.println("Servo motor v1 "); 
}

void loop() {

  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(50);                       // waits 50ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(50);                       // waits 50ms for the servo to reach the position
  }
}
O seară bună tuturor !

vineri, 1 martie 2019

Mini proiectul de vineri (11) - Modul senzor magnetic (Hall)

Descriere proiect:
Astăzi o să testez un senzor Hall, care măsoara un câmp magnetic. Modulul are 4 pini , A0 (tensiunea măsurată de senzor),GND, VCC (5V),D0 (se seteaza la 5 V în momentul în care se atinge pragul setat). Principiul de funcționare a unui senzor Hall se bazează pe semiconductorul Indium antimonide invelit intr-un strat de aluminiu, care detectează un câmp magnetic. Explicațiile fizice sunt un pic mai complicate, dar în mare cam asta ar fi , practic daca un semiconductor, traversat de un curent electric, este supus acțiunii unui câmp magnetic perpendicular pe direcția curentului se manifestă prin apariția unei tensiuni, denumită tensiune Hall.

Documentatie proiect:


Componente:


Schema electronica/sistem:

Cod de test:
// Declaration and initialization of the input pin
int Analog_In = A0; // magnetic field 
int Digital_In = 8; // Threshold reached (ON/OFF)
  
void setup ()
{
  pinMode (Analog_In, INPUT);
  pinMode (Digital_In, INPUT);
       
  Serial.begin (9600); // Serial output with 9600 bps
}
  
// The program reads the current value of the input pins
// and output it via serial out
void loop ()
{
  float Analog;
  int Digital;
    
  // Current value will be read and converted to the voltage
  Analog = analogRead (Analog_In) * (5.0 / 1023.0); 
  Digital = digitalRead (Digital_In);
    
  // and outputted here
  Serial.print ("Analog voltage value:"); Serial.print (Analog, 4);  Serial.print ("V, ");
  Serial.print ("Extreme value:");
  
  if(Digital==1)
  {
      Serial.println (" reached");
  }
  else
  {
      Serial.println (" not reached yet");
  }
  Serial.println ("----------------------------------------------------------------");
  delay (200);
}

Rezultat:
In momentul in care apropii un magnet permanent de senzorul Hall, tensiunea citita scade, se aprinde ledul 2 si se atinge pragul de senzibilitate setat. Pe pinul D0 o sa se citeasca o tensiune de 5 v, care mai departe ar putea fi folosita pentru un intrerupător sau activarea unui alt dispozitiv.

O zi bună tuturor!

duminică, 17 februarie 2019

Fițuica cu formule electronice (4)

Conectarea în serie a condensatorilor:
$$ \bbox[5px,border:2px solid red] { {1 \over C_e }= {1 \over C_1 } + {1 \over C_2 } \\ { C_e }= {{C_1*C_2} \over {C_1 + C_2}} } $$ \(C_e\) - Capacitatea echivalentă
\(C_1 , C_2\) - Capacitatea 1 si 2

Conectarea în paralel a condensatorilor:
$$ \bbox[5px,border:2px solid red] { { C_e }= {{C_1 + C_2}} } $$ \(C_e\) - Capacitatea echivalentă
\(C_1 , C_2\) - Capacitatea 1 si 2

Conectarea în serie a surselor:
$$ \bbox[5px,border:2px solid red] { U_e = {U_1 + U_2 + U_3 + U_4 +\cdots + U_n} \\ U_e = \sum_{i=0}^n U_i } $$ \(U_e\) - Sursa echivalentă
\(U_1 , U_2, U_3 .. U_n\) - Sursa 1 , 2 , 3, .. n

Conectarea în paralel a surselor:
$$ \bbox[5px,border:2px solid red] { U_e = U_1 = U_2 = U_3 = U_4 = \cdots = U_n } $$ \(U_e\) - Sursa echivalentă
\(U_1 , U_2, U_3 .. U_n\) - Sursa 1 , 2 , 3, .. n

Tensiunea Hall \(U_H\) :
$$ \bbox[5px,border:2px solid red] { U_H = {{R_H} * {I * B} \over d} \\ R_H = {1 \over n * e} } $$ \(I\) - Intensitatea curentului electric prin folie.
\(B\) - Inducția câmpului magnetic perpendiculară pe suprafața foliei.
\(R_H\) - Constanta Hall.
\(d\) - grosimea foliei conductoare.
\(n\) - densitatea electronică a foliei conductoare.
\(e\) - sarcina elementară.

Legea I a lui Faraday:
$$ \bbox[5px,border:2px solid red] { m = {k * I * t } } $$ \(m\) - masa substanței descompuse electrolitic .
\(k\) - echivalentul electrochimic.
\(I\) - Intensitatea curentului electric.
\(t\) - timpul.

Legea II a lui Faraday:
$$ \bbox[5px,border:2px solid red] { Q = {n * z * F} \\ F = N_A * e } $$ \(Q\) - Sarcina electrică .
\(n\) - numărul de moli descompuși.
\(z\) - valența substanței.
\(F\) - Constanta lui Faraday = 9.6485309 * \(10^4 C/mol \)
\(N_A\) - Numărul lui Avogadro = 6.0221367 * \(10^{23} mol^{-1} \)
\(e\) - sarcina electrică elementară.

Ecuația diodei ideale:
$$ \bbox[5px,border:2px solid red] { I_D = {I_S} * ( e^{U_D \over U_T} - 1) \\ U_T = {{k * T} \over q} } $$ \(I_D\) - Curentul prin diodă .
\(I_S\) - Curent de saturatie sau curent rezidual sau curent invers.
\(U_D\) -Tensiunea anod-catod la bornele diodei.
\(U_T\) - Tensiunea termica
\(k\) - Constanta lui Bolzman
\(T\) - Temperatura joncțiunii in Kelvin \(K^{\circ}\)
\(q\) - sarcina electronului.

duminică, 10 februarie 2019

Fițuica cu formule electronice (3)

Intensitatea curentului electric:
$$ \bbox[5px,border:2px solid red] { I = {Q \over t} } $$ \(Q\) - Sarcina electrică.
\(t\) - Timpul.

Tensiunea electrică:
$$ \bbox[5px,border:2px solid red] { U = {L \over Q} } $$ \(L\) - Lucrul mecanic în câmp electric.
\(Q\) - Sarcina electrică.

Rezistența electrică :
$$ \bbox[5px,border:2px solid red] { R = {U \over I} } $$ Legea lui Ohm : $$ \bbox[5px,border:2px solid red] { U = R * I (R = constant) } $$ Legea rezistenței:
$$ \bbox[5px,border:2px solid red] { R = {r * l \over S} } $$ \(r\) - Rezistivitatea electrică.
\(l\) - Lungimea conductorului.
\(S\) - Suprafața secțiunii.

Dependeța de temperatură a rezistenței electrice:
$$ \bbox[5px,border:2px solid red] { \Delta{R} = {R_0 * \alpha * \Delta{T} } \\ {R} = {R_0 * (1 + \alpha * \Delta{T}) } } $$ \(\Delta R\) - variația rezistenței.
\(R_0\) - rezistența la 20 C.
\(\alpha\) - coeficientul termic ar rezistivității.
\(\Delta T\) - variația temperaturii.

Energia electrică \(W_e\):
$$ \bbox[5px,border:2px solid red] { W_e = {U * I * t}} $$ Puterea electrică \(P_e\):
$$ \bbox[5px,border:2px solid red] { P_e = {U * I} = {W_e \over t} } $$

vineri, 11 ianuarie 2019

Mini proiectul de vineri (10) - KY-020 Tilt-Switch-module

Descriere proiect:KY-020 Tilt-Switch-module
Azi am testat un senzor de înclinare KY-020 Tilt-Switch, care are o sensibilitate de +/- 15 grade.Senzorul are trei pini (Signal, VCC si GND ) și este foarte usor de conectat. Eu l-am alimentat direct de la Arduino. Pinul de Semnal l-am conectat la pinul 8 de pe placa Arduino. Senzorul ar putea fi folosit în mai multe tipuri de proiecte care implică înclinare. Un exemplu ar fi un ceas cu sonerie (http://www.studiomama.com/on-off), care trebuie sa-l înclini pentru opri alarma. Ar mai putea fi folosit în domeniul automotive, aeronautica etc..

Documentatie proiect:
- KY-020 Tilt-Switch-module

Componente:
- KY-020 Senzor înclinare
- Placa de dezvoltare mega 2560 arduino compatibil

Schema electronica/sistem:

Cod de test:
int tiltPin = 8;      // pin number for tilt switch signal 
int ledPin =  13;     // pin number of LED 
int tiltState = 0;    // variable for reading the tilt switch status

void setup() {  
  pinMode(ledPin, OUTPUT);  // set the LED pin as output      
  pinMode(tiltPin, INPUT);  // set the tilt switch pin as input
   Serial.begin(9600);      // open the serial port at 9600 bps
}

void loop(){
  // get the tilt switch state
  tiltState = digitalRead(tiltPin);

  // check if tilt switch is tilted.
  if (tiltState == HIGH) {     
    digitalWrite(ledPin, HIGH);  
    Serial.println("Not Tilted");       // prints a label
  } 
  else {
    digitalWrite(ledPin, LOW); 
    Serial.println("Tilted");       // prints a label
  }
}
O zi bună tuturor !

miercuri, 2 ianuarie 2019

Mini proiectul de vineri (9) - Detectia monoxidului de carbon folosind senzorul MQ-7

Descriere proiect: Detectia monixidului de carbon folosind senzorul MQ-7
Acest proiect urmărește măsurarea consumului de monoxid de carbon folosind senzorul MQ-7. Măsurarea se face in cicluri de câte 90 de secunde la voltaj de 1.4 . Mai multe informații găsiți pe Instructables. Modulul MQ-7 nu se poate folosi așa cum e, ci are nevoie de un circuit de temporizare care-l activează și citește concentrația de CO câte 90 de secunde iar apoi îl dezaciveaza 60 de secunde. Am construit si eu circuitul și din punctul meu de vedere am obtinut un rezultat bun.

Foarte important !!! Țin să vă atenționez că acest proiect nu a fost testat in condiții reale. NU folosiți acest proiect decât după ce îl testați minuțios.

Documentatie proiect:
- MQ-7 carbon monoxide sensor circuit with Arduino
-MQ-7.pdf
-Arduino-CO-Monitor-Using-MQ-7-Sensor
-Carbon_monoxide
-Monoxid_de_carbon

Componente:
-Senzorul MQ-7
-Atmega2560 Board

Schema electronica/sistem:

Cod de test:
/*
This code was developed by the_3d6 from Ultimate Robotics (http://ultimaterobotics.com.ua). 
License: you can use it for any purpose as long as you don't claim that you are its author and
you don't alter License terms and formulations (lines 1-10 of this file). 
You can share modifications of the code if you have properly tested their functionality, 
including confirming correct sensor response on CO concentrations of 0-30ppm, 100-300ppm and 1000-10000ppm.

If you can improve this code, please do so!
You can contact me at aka.3d6@gmail.com
*/
//Include avr headers.
#include "avr/io.h"

//Include library headers.
#include "timer8.hpp"
#include "timer16.hpp"

//WARNING! Each sensor is different!
//You MUST calibrate sensor manually and
//set proper sensor_reading_clean_air value before using
//it for any practical purpose!

int time_scale = 8; //time scale: we altered main system timer, so now all functions like millis(), delay() etc 
//will think that time moves 8 times faster than it really is
//to correct that, we use time_scale variable:
//in order to make delay for 1 second, now
//we call delay(1000*time_scale)
//LED INDICATOR.
#define DDRLED DDRB
#define OUTLED PORTB

using namespace avr;
float alarm_ppm_threshold = 100; //threshold CO concentration for buzzer alarm to be turned on,
float red_threshold = 200; //threshold when green LED is turned on red turns on
float reference_resistor_kOhm = 10.0; //fill correct resisor value if you are using not 10k reference

float sensor_reading_clean_air = 620; //fill raw sensor value at the end of measurement phase (before heating starts) in clean air here! That is critical for proper calculation
float sensor_reading_100_ppm_CO = -1; //if you can measure it 
//using some CO meter or precisely calculated CO sample, then fill it here
//otherwise leave -1, default values will be used in this case

float sensor_100ppm_CO_resistance_kOhm; //calculated from sensor_reading_100_ppm_CO variable
float sensor_base_resistance_kOhm; //calculated from sensor_reading_clean_air variable

byte phase = 0; //1 - high voltage, 0 - low voltage, we start from measuring
unsigned long prev_ms = 0; //milliseconds in previous cycle
unsigned long sec10 = 0; //this timer is updated 10 times per second,
//when it will overflow, program might freeze or behave incorrectly. 
//It will happen only after ~13 years of operation. Still, 
//if you'll ever use this code in industrial application,
//please take care of overflow problem 
unsigned long high_on = 0; //time when we started high temperature cycle
unsigned long low_on = 0; //time when we started low temperature cycle
unsigned long last_print = 0; //time when we last printed message in serial

float sens_val = 0; //current smoothed sensor value
float last_CO_ppm_measurement = 0; //CO concentration at the end of previous measurement cycle
float opt_voltage = 0;
byte opt_width = 240; //default reasonable value

void setTimer0PWM(byte chA, byte chB) //pins D5 and D6
{
  TCCR0A = 0b10110011; //OCA normal,OCB inverted, fast pwm
  TCCR0B = 0b010; //8 prescaler - instead of system's default 64 prescaler - thus time moves 8 times faster
  OCR0A = chA; //0..255
  OCR0B = chB;
}
void setTimer2PWM(byte chA, byte chB) //pins D11 and D3
{
  TCCR2A = 0b10100011; //OCA,OCB, fast pwm
  TCCR2B = 0b001; //no prescaler
  OCR2A = chA; //0..255
  OCR2B = chB;
}
void setTimer1PWM(int chA, int chB) //pins D9 and D10
{
  TCCR1A = 0b10100011; //OCA,OCB, fast pwm
  TCCR1B = 0b1001; //no prescaler
  OCR1A = chA; //0..1023
  OCR1B = chB;
}

void pwm_adjust()
//this function tries various PWM cycle widths and prints resulting
//voltage for each attempt, then selects best fitting one and
//this value is used in the program later
{
  float previous_v = 5.0; //voltage at previous attempt
  float raw2v = 5.0 / 1024.0;//coefficient to convert Arduino's 
  //analogRead result into voltage in volts
  for(int w = 0; w < 250; w++)
  {
    setTimer2PWM(0, w);
    float avg_v = 0;
    for(int x = 0; x < 100; x ++) //measure over about 100ms to ensure stable result
    {
      avg_v += analogRead(A1);
      delay(time_scale);
    }
    avg_v *= 0.01;
    avg_v *= raw2v;
    Serial.print("adjusting PWM w=");
    Serial.print(w);
    Serial.print(", V=");
    Serial.println(avg_v);
    if(avg_v < 3.6 && previous_v > 3.6) //we found optimal width
    {
      float dnew = 3.6 - avg_v; //now we need to find if current one
      float dprev = previous_v - 3.6;//or previous one is better
      if(dnew < dprev) //if new one is closer to 1.4 then return it
      {
        opt_voltage = avg_v;
        opt_width = w;
        return;
      }
      else //else return previous one
      {
        opt_voltage = previous_v;
        opt_width = w-1;
        return;
      }
    }
    previous_v = avg_v;
  }
}


float raw_value_to_CO_ppm(float value)
{
  if(value < 1) return -1; //wrong input value
  sensor_base_resistance_kOhm = reference_resistor_kOhm * 1023 / sensor_reading_clean_air - reference_resistor_kOhm;
  if(sensor_reading_100_ppm_CO > 0)
  {
    sensor_100ppm_CO_resistance_kOhm = reference_resistor_kOhm * 1023 / sensor_reading_100_ppm_CO - reference_resistor_kOhm;
  }
  else
  {
    sensor_100ppm_CO_resistance_kOhm = sensor_base_resistance_kOhm * 0.5;
//This seems to contradict manufacturer's datasheet, but for my sensor it 
//looks quite real using CO concentration produced by CH4 flame according to
//this paper: http://www.iafss.org/publications/fss/8/1013/view/fss_8-1013.pdf 
//my experiments were very rough though, so I could have overestimated CO concentration significantly
//if you have calibrated sensor to produce reference 100 ppm CO, then
//use it instead    
  }
  float sensor_R_kOhm = reference_resistor_kOhm * 1023 / value - reference_resistor_kOhm;
  float R_relation = sensor_100ppm_CO_resistance_kOhm / sensor_R_kOhm;
  float CO_ppm = 100 * (exp(R_relation) - 1.648);
  if(CO_ppm < 0) CO_ppm = 0;
  return CO_ppm;
}

void startMeasurementPhase()
{
  phase = 0;
  low_on = sec10;
  setTimer2PWM(0, opt_width);
}

void startHeatingPhase()
{
  phase = 1;
  high_on = sec10;
  setTimer2PWM(0, 255);
}
void setLEDs(int br_green, int br_red)
{
  if(br_red < 0) br_red = 0;
  if(br_red > 100) br_red = 100;
  if(br_green < 0) br_green = 0;
  if(br_green > 100) br_green = 100;

  float br = br_red;
  br *= 0.01;
  br = (exp(br)-1) / 1.7183 * 1023.0;
  float bg = br_green;
  bg *= 0.01;
  bg = (exp(bg)-1) / 1.7183 * 1023.0;
  if(br < 0) br = 0;
  if(br > 1023) br = 1023;
  if(bg < 0) bg = 0;
  if(bg > 1023) bg = 1023;

  setTimer1PWM(1023-br, 1023-bg);
}

void setup() {

//WARNING! Each sensor is different!
//You MUST calibrate sensor manually and
//set proper sensor_reading_clean_air value before using
//it for any practical purpose!  
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, INPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  setTimer1PWM(1023, 0);
  analogReference(DEFAULT);
  Serial.begin(9600);

  pwm_adjust();

  Serial.print("PWM result: width ");
  Serial.print(opt_width);
  Serial.print(", voltage ");
  Serial.println(opt_voltage);
  Serial.println("Data output: raw A0 value, heating on/off (0.1 off 1000.1 on), CO ppm from last measurement cycle");

  startMeasurementPhase(); //start from measurement
}

void loop() 
{

//WARNING! Each sensor is different!
//You MUST calibrate sensor manually and
//set proper sensor_reading_clean_air value before using
//it for any practical purpose!

  unsigned long ms = millis();
  int dt = ms - prev_ms;
//this condition runs 10 times per second, even if millis() 
//overflows - which is required for long-term stability
//when millis() overflows, this condition will run after less
//than 0.1 seconds - but that's fine, since it happens only once
//per several days
  if(dt > 100*time_scale || dt < 0) 
  {
    prev_ms = ms; //store previous cycle time
    sec10++; //increase 0.1s counter
    if(sec10%10 == 1) //we want LEDs to blink periodically
    {
      setTimer1PWM(1023, 1023); //blink LEDs once per second
      //use %100 to blink once per 10 seconds, %2 to blink 5 times per second
    }
    else //all other time we calculate LEDs and buzzer state
    {
      int br_red = 0, br_green = 0; //brightness from 1 to 100, setLEDs function handles converting it into timer settings
      if(last_CO_ppm_measurement <= red_threshold) //turn green LED if we are below 30 PPM
      {//the brighter it is, the lower concentration is
        br_red = 0; //turn off red
        br_green = (red_threshold - last_CO_ppm_measurement)*100.0/red_threshold; //the more negative is concentration, the higher is value
        if(br_green < 1) br_green = 1; //don't turn off completely
      }
      else //if we are above threshold, turn on red one
      {
        br_green = 0; //keep green off
        br_red = (last_CO_ppm_measurement-red_threshold)*100.0/red_threshold; //the higher is concentration, the higher is this value
        if(br_red < 1) br_red =1; //don't turn off completely
      }

      setLEDs(br_green, br_red); //set LEDs brightness
    }
  }
  if(phase == 1 && sec10 - high_on > 600) //60 seconds of heating ended?
    startMeasurementPhase();
  if(phase == 0 && sec10 - low_on > 900) //90 seconds of measurement ended?
  {
    last_CO_ppm_measurement = raw_value_to_CO_ppm(sens_val);
    startHeatingPhase();
  }
  int D0=digitalRead(7);
  float v = analogRead(A0); //reading value
  sens_val *= 0.999; //applying exponential averaging using formula
  sens_val += 0.001*v; // average = old_average*a + (1-a)*new_reading
  if(sec10 - last_print > 9) //print measurement result into serial 2 times per second
  {
    last_print = sec10;
    Serial.print(sens_val);
    Serial.print(": Val. senzor |");
    Serial.print(0.1 + phase*1000);
    Serial.print(" |");
    Serial.print(last_CO_ppm_measurement);
    Serial.print(" CO ppm |");
    Serial.println(D0);
  }
}


O zi bună tuturor !

vineri, 24 august 2018

Mini proiectul de vineri (8) - Evitarea de obstacole folosind senzorul FC-51 IR infrarosu

Descriere proiect: Evitarea de obstacole folosind senzorul FC-51 IR infraroșu
Senzorul IR FC-51 este capabil să distingă obiecte obstacol la o distanta de minim 2 cm si maxim 30 cm, deci este perfect pentru roboti. Dacă de exemplu acest robot ar trebui să ajungă din punctul A in punctul B, pentru orientarea la distante foarte mici pentru evitarea obiectelor de pana la 30 cm, atunci acest senzor seteaza semnalul obiect detectat si aprinde LED-ul (vezi imaginea de mai jos). Este foarte ușor de folosit, pentru ca are nevoie doar de VCC (+5v), GND si un port digital de la Arduino. Mai mult pentru o finețe și mai bună această placă are încorporat un potentiometru care poate regla distanta maxim la care se seteaza semnalul.
In imaginea de mai jos se observa emițătorul IR activ. Această fotografie a fost realizată cu telefonul mobil a cărei cameră nu dispune de filtru infrared, din această cauză se observa o lumina slaba violeta. In mod normal ochiul uman nu distinge nimic din spectrul infraroșu, dar cu ajutorul camerei de luat vederi se pot vizualiza pulsurile infraroșii.


Documentație proiect:
senzorul IR FC-51

Componente:
Senzor infrarosu IR FC-51:
-Operation Voltage - 3.3V - 5V
-Detection Angle -35 degrees
-Active Output level - Outputs Low logic level when obstacle is detected
-Detection range: 2cm – 30cm (Adjustable using potentiometer)
-Atmega2560-Mega2560-Board


Schema electronica/sistem:
- VCC - 3.3V-5V DC power input
- GND -0V Power pin
- OUT - Digital Output Pin


Cod de test pentru semnalizarea obstacolului:
int irSenRead =8;
int isObstacle = HIGH;
int LED=6;

void setup() {

  pinMode(irSenRead ,INPUT);
  pinMode(LED ,OUTPUT);
  Serial.begin(9600);
}

void loop() {

  isObstacle = digitalRead(irSenRead); // // Read IR sensor output
   Serial.println(digitalRead(irSenRead)); // // print the output

  // // isObstacle ==low there is obstacle infront of sensor
  // // using serial monitor we can see this output
  if (isObstacle == LOW) {
    Serial.println("OBSTACLE");
    digitalWrite(LED ,HIGH);
  }
  else
  {
    Serial.println("NO");
    digitalWrite(LED ,LOW);
  }

  delay(500);
}
Citirea receptorului IR folosind biblioteca IRemote:
/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include "IRremote.h"

int RECV_PIN = 8;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  // In case the interrupt driver crashes on setup, give a clue
  // to the user what's going on.
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Enabled IRin");
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  delay(100);
}
Weekend plăcut tuturor !

vineri, 17 august 2018

Mini proiectul de vineri (7) - Masurarea temperaturii si umiditatii folosind senzorul DHT11

Descriere proiect:Masurarea temperaturii si umiditatii folosind senzorul DHT11. Pentru a măsura temperatura si umiditatea cel mai simplu de folosit este senzorul DHT11. Conectarea lui este simpla si rezultatul măsurătorii este de încredere. În plus libraria idDHT11 returneaza temperatura in toate unitatile de măsura a temperaturii Celsius, Kelvin si Fahrenheit.
În imaginea de mai jos se poate observa conectarea senzorului la Atmega2560, Pin 1 DHT11 la 5V, Pin 2 DHT11 la Pinul 2 Arduino, Pin 3 DHT11 e neconectat si Pin 4 DHT11 se conecteaza la GND. Inre pinul 1 si 2 am conectat o rezistenta de 10K:
Documentatie proiect:
DHT11-Technical-Data-Sheet
How-to-set-up-the-dht11-humidity-sensor-on-an-arduino
Componente:
- Senzor de temperatura si umiditate
Schema electronica/sistem:
Afisarea umiditatii si temperaturii:

Cod de test:
/*
  Board            int.0   int.1   int.2   int.3   int.4   int.5
 Uno, Ethernet    2   3
 Mega2560   2   3   21    20    19    18
 Leonardo   3   2   0   1
 Due            (any pin, more info http://arduino.cc/en/Reference/AttachInterrupt)
 
 This example, as difference to the other, make use of the new method acquireAndWait()
 */

#include "idDHT11.h"

int idDHT11pin = 2; //Digital pin for comunications
int idDHT11intNumber = 0; //interrupt number (must be the one that use the previus defined pin (see table above)

//declaration
void dht11_wrapper(); // must be declared before the lib initialization

// Lib instantiate
idDHT11 DHT11(idDHT11pin,idDHT11intNumber,dht11_wrapper);

void setup()
{
  Serial.begin(9600);
  Serial.println("idDHT11 Example program");
  Serial.print("LIB version: ");
  Serial.println(IDDHT11LIB_VERSION);
  Serial.println("---------------");
}
// This wrapper is in charge of calling 
// mus be defined like this for the lib work
void dht11_wrapper() {
  DHT11.isrCallback();
}
void loop()
{
  Serial.print("\nRetrieving information from sensor: ");
  Serial.print("Read sensor: ");
  //delay(100);
  
  int result = DHT11.acquireAndWait();
  switch (result)
  {
  case IDDHTLIB_OK: 
    Serial.println("OK"); 
    break;
  case IDDHTLIB_ERROR_CHECKSUM: 
    Serial.println("Error\n\r\tChecksum error"); 
    break;
  case IDDHTLIB_ERROR_ISR_TIMEOUT: 
    Serial.println("Error\n\r\tISR time out error"); 
    break;
  case IDDHTLIB_ERROR_RESPONSE_TIMEOUT: 
    Serial.println("Error\n\r\tResponse time out error"); 
    break;
  case IDDHTLIB_ERROR_DATA_TIMEOUT: 
    Serial.println("Error\n\r\tData time out error"); 
    break;
  case IDDHTLIB_ERROR_ACQUIRING: 
    Serial.println("Error\n\r\tAcquiring"); 
    break;
  case IDDHTLIB_ERROR_DELTA: 
    Serial.println("Error\n\r\tDelta time to small"); 
    break;
  case IDDHTLIB_ERROR_NOTSTARTED: 
    Serial.println("Error\n\r\tNot started"); 
    break;
  default: 
    Serial.println("Unknown error"); 
    break;
  }
  Serial.print("Humidity (%): ");
  Serial.println(DHT11.getHumidity(), 2);

  Serial.print("Temperature (oC): ");
  Serial.println(DHT11.getCelsius(), 2);

  Serial.print("Temperature (oF): ");
  Serial.println(DHT11.getFahrenheit(), 2);

  Serial.print("Temperature (K): ");
  Serial.println(DHT11.getKelvin(), 2);

  Serial.print("Dew Point (oC): ");
  Serial.println(DHT11.getDewPoint());

  Serial.print("Dew Point Slow (oC): ");
  Serial.println(DHT11.getDewPointSlow());

  delay(1000);
}
Codul l-am preluat de aici .
O zi bună tuturor !

joi, 16 august 2018

Mini proiectul de vineri (6) - Masurarea distantei folosind HC-SR04

Descriere proiect: Măsurarea distanței folosind HC-SR04
Având în dotare de ceva vreme un senzor ultrasonic de 40kHz am decis să încerc să-l pun în funcțiune. După ceva documentare conștiincioasă am constatat că e destul de simplu de conecta pentru ca are doar 4 pini VCC, TRIG, ECHO si GND. Apoi am facut calculele pentru o viteza a sunetului de 340 m/s și am calculat distanța pe baza duratei întoarcerii sunetului la receptor. Totul a mers fără nici o problemă. Senzorul are o rezolutie de minim 2 cm si maxim 4 metrii. Unda sonora este emisa de transmițător, se loveste de un obiect si se intoarce la receptor. Pe baza vitezei sunetului și a formulei de calcul a timpului rezultă formula distanței = timp * 0.034/2. Acest mini proiect probabil o să-l folosesc la dronă sau la un eventual proiect de masinuță autonomă.
În prima imagine am prins si calculele facute pentru un exemplu de obiect aflat la 10 cm de senzor. Iar mai jos se văd desenate semnalele senzorului si ordinea lor, in prima faza se seteaza pe high trigerul pentru 10 us iar apoi urmeaza 8 ropote (burst) :D de semnal urmate de semnalul de echo.

Documentatie proiect:

NewPing lib
Wiki ultrasound
Componente:
HC-SR04 pe robofun
HC-SR04 pe Amazon
Atmega2560-Mega2560-Board
Schema electronica/sistem:
Aici se poate observa conexiunea senzorului la placa Atmega2560:
Aici am testat măsurarea distantaței până la caiet:

Cod de test:
Cel mai simplu cod pentru masurarea distantei folosind doar setarea pinilor:
/*
* Ultrasonic Sensor HC-SR04
*
*/
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distance;

void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm ");
}

Codul sursa pentru masurarea distantei folosind libraria NewPing:
/*
* Ultrasonic Sensor HC-SR04
*
*/
#include "NewPing.h"

// defines variables
long duration;
int distance;
// defines pins numbers
#define TRIG_PN 9
#define ECHO_PN 10
#define MAX_DIST 400
#define MIN_DIST 2
NewPing sonar(TRIG_PN,ECHO_PN,MAX_DIST);

void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}
void loop() {
// Calculating the distance
distance= sonar.ping_cm();
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
if((distance >= MAX_DIST) || (distance <= MIN_DIST))
{
Serial.println("Out of range ");
}
else
{
Serial.print(distance);
Serial.println(" cm ");
}
}

O zi plăcută tuturor !