vineri, 18 aprilie 2014

Raspberry Pi - prima impresie

   Deoarece am fost, cat de cat, cuminte, am primit un Paspberry Pi insotit de un card de 8Gb si un alimentator de 5V/1A.
   Raspberry Pi este un "computer (capabil sa ruleze Linux) de dimensiunea unui card de credit, cu placa de retea Ethernet inclusa, conector HDMI, 2 port-uri USB, 512 MB RAM, procesor ARM la 700 MHz".
   Am facut cateva poze mai detaliate ale placii si accesoriilor





   Punand cardul SD intr-un cititor am descoperit ca am mai multe sisteme de operare.
   M-au uitat pe cutia in care fusese placa si cardul si era scris sa vizitez adresa http://www.element14.com/raspberrypi si am descoperit ca pe card este o aplicatie numita NOOBS, cu care pot instala unul din cele 6 sisteme de operare:
- Arch Linux
- OpenELEC (Xbox Media Centre)
- Pidora
- RISC OS
- RaspBMC (Xbox Media Centre)
- Raspbian
   Tot pe acolo am gasit un articol numit Installing OS With NOOBS... in care se prezinta modul cum se instaleaza un sistem de operare folosind interfeta NOOBS...
   Desi sunt mai multe filmulete explicative, am pe primul gasit numit NOOBS: The Easiest Raspberry Pi Setup
   Nu sust total pregatit pentru teste, dar astept sa-mi vina o carcasa si un cablu adaptor HDMI la VGA (pentru a folosi un monitor de calculator).
(23.05.2014 - Din pacate, cablul adaptor HDMI-VGA nu functioneaza, trebuie un adaptor HDMI la VGA).

   Din primele informatii, am descoperit ca Raspberry Pi nu are intrari analogice, dar se poate folosi de un Arduino, cu care sa comunice pe protocol i2c prin intermediul unei interfete bidirectionale (deoarece Raspbbery nu accepta decat nivel logic de 3,3V iar Arduino lucreaza cu 5V). 
 
   In articolul numit Raspberry Pi with I2C-Arduino-Slave se gaseste prezentat acest mod de comunicare:
    Ca un rezumat, primele impresii sunt bune... urmeaza in curand teste si experimente, dupa sarbatorile de Paste...

miercuri, 16 aprilie 2014

Indicator date mediu pentru masina (3)

   Dupa o mica pauza, am reluat partea cu indicatorul de date mediu pentru masina:
- temperatura exterioara, masura cu un senzor DS18B20
- temperatura si umiditate interior masina, masurate cu senzorul DHT11
- tensiunea de pe baterie (acumulator), prin intermediul unui divizor rezistiv.
   Partea descriptiva am prezentat-o in articolul Indicator date mediu pentru masina, iar partea cu teste cu Arduino in articolul Indicator date mediu pentru masina (2), dar ideea a fost sa pun pe masina un montaj independent, asa ca am desenat cu ajutorul programului Eagle PCB Software o schema, dupa care am desenat si cablajul.
   Cablajul a fost realizat de Cristi din Satu Mare, prin metoda transferului de tonner de la o imprimanta laser.
   Am dat gauri in cablaj si m-am apucat de plantat si lipit piesele:
   Dupa ce am pus minimul de piese necesare, am conectat interfata USB si am alimentat si incarcat sketch-ul:
   Neavand intrarile conectate, apar mesaje ciudate la tensiune si temperaturi, dar e bine din punct de vedere al functionarii, dupa cum vedeti si in filmuletul indicator mediu - masina (II)
   A urmat trecelea la alimentarea dintr-o sursa stabilizata reglabila cu tensiunea de 14,5V (valoarea maxima de pe masina) si am lasat vreo 8 ore si nu s-a incalzit regulatorul de tensiune de tip 7805, iar prezentarea experimentului este in filmuletul indicator mediu - masina (III)
   Alimentatorul reglabil folosit de mine a fost prezentat in articolul LM317 si este realizat dupa o schema publicata in Almanahul Tehnium din 1990, iar despre partea de stabilizare de 5V folosita pe placa puteti citi in articolul 78xx.
   Sketch-ul trebuie modificat un pic fata de cel prezentat in articolul Indicator date mediu pentru masina (2) deoarece sunt folositi alti pini pentru afisaj:
// http://nicuflorica.blogspot.ro/2014/04/indicator-date-mediu-pentru-masina-3.html
// original sketch by niq_ro
#include <LiquidCrystal.h>
// folosesc libraria pentru afisaje LCD simple
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// indic modul de legare, vezi mai jos:
/*                                    -------------------
                                      |  LCD  | Arduino |
                                      -------------------
 LCD RS pin to digital pin 7          |  RS   |   D7    |
 LCD Enable pin to digital pin 8      |  E    |   D8    |
 LCD D4 pin to digital pin 9          |  D4   |   D9    |
 LCD D5 pin to digital pin 10         |  D5   |   D10   |
 LCD D6 pin to digital pin 11         |  D6   |   D11   |
 LCD D7 pin to digital pin 12         |  D7   |   D12   |
 LCD R/W pin to ground                |  R/W  |   GND   |
                                      -------------------
*/
// http://arduino.cc/en/Reference/LiquidCrystalCreateChar

byte grad[8] = {
  B01100,
  B10010,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
};

// variables 

float R1, R2, R3; // rezsistors in voltage divisor
float k1; // adjustment for divisor
float u1, u11, u12; // for voltage

int ti; // temperature inside of car;

// data
int VPin = A0; // voltage pin
int DHTPin = A1; // data pin from DHT11
//int DSPin = A2; // 

// for DHT11 sensor
#include "DHT.h"
#define DHTPIN A1     // what pin we're connected to
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);



#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 10 on the Arduino
#define ONE_WIRE_BUS A2
#define TEMPERATURE_PRECISION 9
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
// arrays to hold device addresses
DeviceAddress outsideThermometer;


void setup() {

R1 = 4.7; // R1 = 4k7
R2 = 10;  // R2 = 10k
R3 = 4.7; // R3 = 4k7
k1 = 1/1.033;


  lcd.createChar(0, grad);
    
  lcd.begin(16, 2); // set up the LCD's number of columns and rows: 
 
// initialing the DHT11 sensor;
dht.begin();

 lcd.clear(); // clear the screen
 lcd.setCursor(1, 0); // put cursor at colon 2 and row 0 = left/up
 lcd.print("indicator bord"); // print a text
 lcd.setCursor(2, 1); // put cursor at colon 0 and row 0 = left/down
 lcd.print("1.0 by niq_ro"); // print a text
 delay (2000);
 lcd.clear(); // clear the screen
 
// Start up the DS18B20 sensor
  sensors.begin();
// adress for ds sensor  
//   DeviceAddress outsideThermometer  = { 0x28, 0xAC, 0x7A, 0xD4, 0x04, 0x00, 0x00, 0x7E };
//  DeviceAddress outsideThermometer = { 0x28, 0xAC, 0x7A, 0xD4, 0x4, 0x0, 0x0, 0x7E };
// set the resolution to 9..12 bit
  sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);


} // END void setup




  
void loop(){
  
u1 = analogRead(VPin);
u11 = k1*5.0*u1/1023*(R1+R2+R3)/R1;
u12 = u11 + 0.05;
//u12=11.4; // for test
// u12=7.5;  //for test;

if (u12<10.0)
{
  lcd.setCursor(12, 0);
  lcd.print(u12,1);
  lcd.print("V");
  delay(500);
  lcd.setCursor(12, 0);
  lcd.print("    ");
  }  
else
{
  lcd.setCursor(11, 0);
  lcd.print(u12,1);
  lcd.print("V");
  delay(500);
}

// DHT11 part
 int h = dht.readHumidity();
 int ti = dht.readTemperature();

  lcd.setCursor(0, 1);
  lcd.print("int:");
//ti=0; // for test;
//ti=7;  // for test;
//ti=29;  // for test;
  if (ti<1) {
  lcd.setCursor(5, 1);
  lcd.print(" 0");
  lcd.write(byte(0));
  lcd.print("C");
  delay(500);
  lcd.setCursor(5, 1);
  lcd.print("     ");
  }
  else
  if (ti>=9) {
  lcd.setCursor(4, 1);
  lcd.print("+");
  lcd.print(ti);
  lcd.write(byte(0));
  lcd.print("C");
  }
  else
  //if (ti>=1 || ti<10)
  {
  lcd.setCursor(5, 1);
  lcd.print("+");
  lcd.print(ti);
  lcd.write(byte(0));
  lcd.print("C");
  }

  lcd.setCursor(11, 1);
  lcd.print(h);
  lcd.print("%um");

// 
 DeviceAddress outsideThermometer = { 0x28, 0xAC, 0x7A, 0xD4, 0x4, 0x0, 0x0, 0x7E };
 sensors.requestTemperatures();
 float te = sensors.getTempC(outsideThermometer);
// printTemperature(DeviceAddress outsideThermometer);
 delay(300);
//te=-24;
//te=-2;
//te=-0.4;
// te=0;
//te=0.3;
//te=5;
//te=17;
//te=17.6;


lcd.setCursor(0, 0);
lcd.print("ext:");


if (te<-10) {
 lcd.setCursor(4, 0);
 lcd.print(te,0);
lcd.write(byte(0));
lcd.print("C   ");
}
else
if (te>-10 || te<0) {
  lcd.setCursor(5, 0);
lcd.print(te,0);
lcd.write(byte(0));
lcd.print("C   ");
}

else
if (te=0) {
lcd.setCursor(5, 0);
lcd.print("=0");
lcd.write(byte(0));
lcd.print("C   ");
}

if (te>0) 
{
lcd.setCursor(5, 0);
lcd.print("+");
lcd.print(te,0);
lcd.write(byte(0));
lcd.print("C   ");
}

if (te>=10) {
lcd.setCursor(4, 0);
lcd.print("+");
lcd.print(te,0);
lcd.write(byte(0));
lcd.print("C   ");
}
}   
   Am pus si rezistentele si senzorii si, am costatat ca noul senzor DHT11 consuma peste 1A, undeva la 1,2A.. si se incinge rau LM7805... l-am deconectat si am pus altu' si acum e ok... consumul montajului este de aproximativ 30mA..
 
   Ce am testat arata ca in filmuletul indicator mediu - masina (IV)
   La un consum exagerat (peste 1A) nu au avut nicio sansa stabilizatoarele de tensiune de pe placile Arduino la testele anterioare... 

luni, 7 aprilie 2014

Resetare multifunctionale Canon MP180 (sau similare)

   Am un multifunctional Canon MP180 (imprimanta cu jet de cerneala si scaner + "copiator"), care a inceput sa ma "supere", in sensul ca listez foarte putine pagini si ma trezesc ca am cartusele goale, am eroare la recunoastere cartuse si atunci nu pot nici macar scana..
   L-am achizitionat acum ceva ani, in ideea de a-l folosi pentru uz caznic, sa zic asa... cu toata aceasta "grija" pentru multifunctional, am fost fost nevoit sa cumpar cateva cartuse noi, ca ori se "ardeau cip-urile" ori se infundau "diuzele" ca il foloseam prea rar..
   Cu toate ca aceaste cartuse au "cip"-uri, ele se pot reseta si reincarca de cateva ori... cel color,e mai sensibil si se cam "arde"... dupa o perioada trebuie "resetata" si imprimanta astfel incat sa recunoasca cartusele incarcate.
   Un utilitar, rusesc, se pare, care face acest lucru, este MPTool.. pe care un l-am gasit pe un blog lituanian in articolul MPTool Multi Resetter For Canon MP si acolo se mentioneaza ca  e bun pentru seriile MP150, MP160, MP170, MP180, MP450, MP460.

   Pentru a aduce imprimanta in modul de service, se parcurg etapele:
   1) Se scoate stecherul din priza (sau daca prelungitorul in care este introdus are intrerupator, se deconecteaza alimentarea de acolo)
   2) Se tine apasat butonul ON/OFF (de pornire/oprire) si se alimenteaza multifunctionalul
   3) Cand LED-ul indicator e verde, se apasa si apoi se elibereaza butonul STOP/RESET (simbolul este de triunghi intors cu varful in jos intr-un cerc rosu)
   4) Se elibereaza butonul ON/OFF
   LED-ul aprins in verde se stinge, iar cel de avarie se va aprinde in culoarea galbena, indicand intrarea in modul de service.
   Calculatorul va "vedea" o noua imprimanta (care va ramane si ulterior, putand fi redenumita pentru a nu apare confuzii, cu un nume de genul Canon Service Mode)

   Deschideti utilitarul si resetati contoarele celor 2 cartuse (Reset Counters - Reset Blank si apoi Reset Color)
   Se opreste imprimanta si se scoate stecherul din priza si se reporneste. 


22.04.2014
   Niste "printscreen"-uri din timpul rescrierii EEPROM-ului:
 
 
 
   

duminică, 6 aprilie 2014

Resetare multifunctional Canon Pixma MP250

   La multifunctionalul Canon MP250, dupa un anumit numar de ore, apare eroarea E07, care o blocheaza.. nu se mai poate lista, scana sau copia...

  
   Pentru a putea reseta imprimanta trebuie sa o "aducem in modul de service", aceasta se faci parcurgand pasii:
   0) se pun hartii in compartimentul de stocare, deoarece imprimanta va scoate cateva pagini scrise sau nu;
   1) se opreste imprimanta, daca e pornita; se deconecteaza si cablul USB
   2) cand imprimanta e oprita se apasa butonul START/STOP (sau RESUME/CANCEL), care arata ca un cerc cu un triunghi cu varful injoc, de culoare rosie) si e amplasat in partea dreapta/jos.
   3) Tinand butonul apasat, se apasa si se tine apasat butonul ON/POWER
   4) Cand s-a aprins LED-ul de POWER in verde, se elibereaza butonul START, tinand in continuare apasat butonul POWER
   5) Cu butonul POWER apasat se apasa de 2 ori pe butonul START, apoi se da drumul la butonul POWER si se asteapta pana apare cifra 0 (zero pe ecran)
   6) Dupa ce apare cifra 0 se conecteaza la calculator cablul USB, iar calculatorul detecteaza o imprimanta.
   Inainte de aceasta trebuie sa descarcam de pe net programul ServiceTool versiunea 1074.. mie, doar asta mi-a functionat.
   Dupa ce se deschide programul se apasa pe tipul de soft si se poate schimba din JPN in EUR (optional) si se apasa pe resetare contor cerneala (CLEAR INK COUNTER) prin apasarea butonului MAIN
   Dupa ce imprimanta "mesteca" ceva timp si listeaza niste pagini, trebuei apasat pe butonul EEPROM Clear si apoi pe EEPROM.
   Apoi se opreste imprimante si reporneste... si.. gata...
   Pe site-ul SYBILHICKIE se prezinta maisimplu cele 3 etape:
   PS:Se poate folosi si programul ServiceTool E500 care face mai multe operatii singur:

vineri, 4 aprilie 2014

Marirea preciziei de masurarea de la 10 la 12biti la placa Arduino

   Placa Arduino are 6 intrari analogice, de fapt sunt 6 convertoare digital-analogice pe 10 biti (tensiunea de referinta este impatita in 210-1=1023 intervale). De obicei, tensiunea de referinta este 5V, deci rezolutia este de 4,89mV. Daca se foloseste referinta interna (cu ATmega328 sau ATmega168), care are valoarea de 1,1V, rezolutia este de 1,075mV.
   Despre acest mod de masurare gasiti multe in articolul Convertor analogic-numeric de pe Wikipedia.
   Am gasit un integrat destul de ieftin, ADC121S021 la pretul de cca. 9lei (2 EURO), care este un convertor digital-analogic pe 12 biti, deci tensiunea de intrare este impartita in 212-1=4095 intervale, rezolutia fiind de 1,22mV cand tensiunea de referinta este de 5V, respectiv 0,69mV cand este utilizata referinta interna de 1,1V, deci de 4 ori fata de cele interne de pe placa Arduino.
   In fisa de catalog (datasheet) se gasesc destule informatii.
   Integratul are 6 pini (in capsula SMD/SOT-23 si mai mica LLP):
iar schema bloc:
- VIN = intrarea analogica intre 0 si tensiunea de alimentare (VA);
- SCLK = intrare digitala: impulsuri tact (ceas)
- SDATA = iesire digitala: se transmit date cand exista impulsuri de ceas;
- CS = selectie integrat.
   Cand pe pinul CS este 1 logic, integratul este blocat, aceasta permite conectarea mai multor convertoare analog-digitale.

   La o cautare mai atenta am dat de MCP3204, care este un convertor analog-digital pe 12biti si 4 canale, respectiv MCP3208 cu 8 canale, ambele la cca. 12lei.
   Pe site-ul german Arduino-Projekte.de am gasit articolul 12-bit A/D-Wandler von Microchip (MCP3208/MCP3204)
in care se gaseste libraria libraria AH_MCP320x.h si un sketch
// http://arduino.alhin.de/arduino_code/MCP3208_ADC_SPI.ino
// SELPIN   10   //Selection Pin (CS)
// DATAOUT  11   //MOSI 
// DATAIN   12   //MISO 
// SPICLOCK 13   //Clock

#include "AH_MCP320x.h"
#include <SPI.h>

int ADCValue = 0;
float time_in;
float time_out;


AH_MCP320x ADC_SPI(10);             //Object definition with D10 as CS, other pins are defined by spi interface (faster mode).
//AH_MCP320x ADC_pin(10,11,12,13);  //Object definition with free definition of communication pins (slower mode).

void setup()
{
  Serial.begin(57600);
}

void loop()
{  
  for(int i=0;i<8;i++)   // i<8 at MCP3208 
  {  
    Serial.print("CH"); 
    Serial.print(i);     
    Serial.print(": ");   
    time_in = micros();  
    ADCValue = ADC_SPI.readCH(i);      //read analog value from IC (SPI mode)
//  ADCValue = ADC_pin.readCH(i);      //read analog value from IC (Pin mode)   
    time_out = micros();
    
    Serial.println(ADCValue);   
    
    Serial.print("Voltage:");
    Serial.print(ADC_SPI.calcVOLT(5.0,ADCValue));     //calculate the input voltage at 5V VREF
//    Serial.print(ADC_pin.calcVOLT(5.0,ADCValue));   //calculate the input voltage
    Serial.println(" V");
    
    Serial.print("Time: ");     
    Serial.print(time_out-time_in);   
    Serial.println(" ms");     
    Serial.println();
  
    delay(10);
  }
  delay (1000);
}
   De asemenea, in articol se prezinta si instructiunile folosite in librarie. 
   Pe site-ul Arduino se gaseste un articol numit MCP3208, care prezinta si acolo integratul, incluzand si un sketch.
   In datasheet (fisa tehnica) sunt prezentate cele 2 integrate MCP3204/3208, schema bloc este:
   Semnificatia pinilor este:
- CH0..CH3 la MCP3204, respectiv CH0..CH7 la MCP3208 sunt intrari analogice;
- VREF - tensiunea de referinta (tensiunea masima corespunzatoare "treptei" 4095);
- CLK - intrare digitala: impulsuri tact (ceas);
- DIN - intrare digitala, selecteaza intrarea;
- DOUT - iesire digitala, transmite datele convertite;
- CS/SHDN - selectie integrat.
   Cand pe pinul CS este 1 logic, integratul este blocat, aceasta permite conectarea mai multor convertoare analog-digitale, cum se vede in imaginea de mai jos, prezentata in articolul SPI communication with external ADC MCP3

21.04.2014
   Pentru placa Raspberry Pi, care nu are deloc intrari analogice, se poate folosi si un MCP3008, care are 8 canale sau MCP3004, care are 4 canale si, ambele, au rezolutie de 10 biti... similara placilor Arduino..
  

MCP4921(4922) = convertor digital/analog pe 12 biti

 Erata: din greseala prezentasem aceste convertoare ca analog/digitale.
  
   Cautand un convertor digital-analog la un pret decent, am descoperit perechea MCP4921/4922, care sunt pe 12 biti, deci la iesire tensiunea este impartita in 212-1=4095 intervale, rezolutia fiind de 1,22mV cand tensiunea de referinta este de 5V, respectiv 0,69mV cand este utilizata referinta interna de 1,1V.
   Multe informatii se gasesc in fisa tehnica (datasheet), dar pot fi prea complicate asa ca trecem la partea mai practica...
   Pe site-ul Arduino se gaseste un articol numit SPI library care prezinta modul de conectare al comunicatiei seriale SPI, daa nici asta nu "atrage", asa ca trecem la alte articole..
   Pe un site german am gasit un articol numit 12bit D/A-Wandler von Microchip (MCP4921, MCP4922) in care sunt si poze intuitive:
dar are si o librarii si 2 sketch-uri cu exemple:
   Autorul articolului mentioneaza ca sursa de inspiratie blogul sinneb, unde este articolul MCP4921 12bit DAC voltage controller
iar autorul acestuia recomanda articolul Controlling a Gakken SX-150 synth with Arduino.
   Pe site-ul tronixstuff exista un articol numit Tutorial: Arduino and the SPI bus part II care prezinta pe MP4921:
   Sketch-ul prezentat acolo este:
/*
 Example 36.2 - SPI bus device demo using a Microchip MCP4921 DAC [http://bit.ly/j3TSak]
 http://tronixstuff.com/tutorials > chapter 36 | CC by-sa-nc | John Boxall
*/
 
#include "SPI.h" // necessary library
int del=0; // used for various delays
word outputValue = 0; // a word is a 16-bit number
byte data = 0; // and a byte is an 8-bit number
void setup()
{
  //set pin(s) to input and output
  pinMode(10, OUTPUT);
  SPI.begin(); // wake up the SPI bus.
  SPI.setBitOrder(MSBFIRST);
}
 
void loop()
{
  for (int a=0; a<=4095; a++)
  {
    outputValue = a;
    digitalWrite(10, LOW);
    data = highByte(outputValue);
    data = 0b00001111 & data;
    data = 0b00110000 | data;
    SPI.transfer(data);
    data = lowByte(outputValue);
    SPI.transfer(data);
    digitalWrite(10, HIGH);
    delay(del);
  }
  delay(del+25);
  for (int a=4095; a>=0; --a)
  {
    outputValue = a;
    digitalWrite(10, LOW);
    data = highByte(outputValue);
    data = 0b00001111 & data;
    data = 0b00110000 | data;
    SPI.transfer(data);
    data = lowByte(outputValue);
    SPI.transfer(data);
    digitalWrite(10, HIGH);
    delay(del);
  }
  delay(del+25);
}