marți, 15 ianuarie 2019

Zile libere și vacanțe școlare 2019

Vacanțe școlare:

  • Vacanța de iarnă (22 decembrie 2018 – 13 ianuarie 2019)
  • Vacanța intersemestriala (2 – 10 februarie 2019)
  • Vacanța de primavară (20 aprilie – 5 mai 2019)
  • Vacanța de vară (15 iunie – 15 septembrie 2019)


Sărbători legale:

  • 1 ianuarie (Marți), 2 ianuarie (Miercuri) — Anul Nou
  • 24 ianuarie (Joi) — Ziua Unirii Principatelor Române
  • 26 aprilie (Vinerea mare), 28 - 29 aprilie — Paște ortodox
  • 1 mai (Miercuri)— Ziua Muncii
  • 1 iunie (Duminică) - Ziua Copilului
  • 16 iunie (Duminică), 17 iunie (luni) — Rusalii
  • 15 august (Joi) — Adormirea Maicii Domnului
  • 30 noiembrie (Sâmbătă)— Sfântul Andrei
  • 1 decembrie (Duminică) — Ziua Națională a României
  • 25 decembrie (Miercuri), 26 decembrie (Joi) — Crăciunul

#vacanțe #sărbători

Meștereala de luni (5) - Reparatie căști cu bluetooth rupte

Din ciclul articolelor "Meștereala de luni" am încercat sa repar bareta de plastic prin lipirea unui semicerc de plastic peste. Din pacate rezultatul nu e prea bun din cauza faptului că bareta a devenit acum prea rigidă. Rezultatul reparației este funcțional dar nu sunt prea mulțumit. Nici lipitura nu e prea reușită. O sa încerc sa realizez un semicerc mai subțire și implicit mai flexibil. Probabil o sa revin cu un update săptămâna viitoare, dacă nu am alteceva mai interesant de reparat. Vedeti mai jos modelul și rezultatul reparației.
Model:

Rezultat:
O zi bună tuturor !

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 !

Știri din domeniul embedded systems and software [11/01/2019]

microcontroller board by Arnau ramos Oviedo on 500px.com



Weekend plăcut tuturor !

luni, 7 ianuarie 2019

Meștereala de luni (4) - Cleme prindere pentru aspirator

Clemele de la aspirator s-au rupt și practic l-a facut de nefolosit. Rezervorul unde se strânge praful nu mai stă fixat și implicit praful nu s-ar mai strânge. Imprimanta mea 3D m-a salvat încă odată, si am reușit să creez niște cleme solide pe care le-am fixat cu holșuruburi. E un pic inestetică soluția mea dar funcționează foarte bine. Aspiratorul este salvat :D ...
Model 3D:
Cleme prindere pentru aspirator
Model clema prindere pentru aspirator

Rezultat:

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 !

luni, 31 decembrie 2018


Meștereala de luni (3) - Suport HDD extern

Organizarea este foarte importantă pe un birou, și din această cauzp am considerat util un suport pentru HDD extern. Specificațiile ar fi simple: să stea fix și să nu aibă șocuri fizice :D .
Modelul 3d l-am realizat cu Tinkercad și totul a decurs foarte ușor și rapid. În mai puțin de 30 de minute am montat suportul.
Model 3D:
Suport HDD extern

Rezultat:
Are rost să mai precizez că am măsurat fortele care tensionează suportul și care m-au ajutat să-l dimensionez pentru o susținere optimă.... :D

La mulți ani și An Nou Fericit!