Hi!

Publié: 15/02/2011 dans Base
Tags:, ,

Bienvenue sur mon machin où y’aura des trucs dedans, là!

Parait que c’est à la mode d’avoir ça, bon ben voilà, ça c’est fait!

(PS: Si vous êtes sous IExplore, sortez vite avant que cela n’explose et rechargez la page sous Firefox!!! Téléchargez Firefox)


//Licenced under GNU General Public Licence more details here
// openenergymonitor.org
/////////////////////////EnergyWebDuino V7 rev7.1 – 29/03/16 – Sagittarius ©2016/////////////////////////////
//// Ethernet
#include <Ethernet.h>
#include <SPI.h>
//#include <Wire.h>
#include <DS1302.h>
//////———————————————————–

//// Mem
#include <pgmspace.h> // for progmem
#define P(name) static const prog_uchar name[] PROGMEM // declare a static string
//////———————————————————–

//// 1302 RTC
int DS1302CLKPin=6;
int DS1302IOPin=7;
int DS1302CEPin=8;
static unsigned long msTick =0; // the number of Millisecond Ticks since we last
//////———————————————————–
//// V/I input sensors
//Set Voltage and current input pins
int inPinI = 5;//=>Ana
const int inPinV = 4;//=>Ana
int inPinI2 = 2;//=>Ana
//////———————————————————–
//// Pulse count
/*—–( Declare Constants )—–*/
#define ANALOG_SENSOR_PIN A3 //=>Ana
#define DIGITAL_SENSOR_PIN 5 //=>Digi
#define LEDPIN 13 //=>Digi The onboard LED
#define cpt1 0//=>Digi RX Teleinfo
int Counter = 0;

/*—–( Declare Variables )—–*/
int switch_state; /* Holds the last digital value */
int LightAnalogValue; /* Holds the last analog value */
unsigned long pulseCount = 0; // Counts power pulses in interrupt, 1 pulse = 1 watt
unsigned long pulseTotal = 0; // Total power used since the sketch started
volatile int pulseFlag = 0;
//////———————————————————–

//// RTC int
char buf[50]; // time output string for debugging
DS1302 rtc(DS1302CEPin, DS1302IOPin, DS1302CLKPin);
//////———————————————————–

//// KWh prod
int last_hour = 0;
int hour = 12, minute = 0, second = 0;
double usekwh = 0, genkwh = 0;
double usewh =0, genwh = 0;
double use_history[7], gen_history[7];
int cval_use, cval_gen;
byte page = 1;
unsigned long fast_update, slow_update;
//const int SolarPV_type=1; // Select solar PV wiring type – Type 1 is when use and gen can be monitored seperatly. Type 2 is when gen and use can only be monitored together, see solar PV application documentation for more info
const int maxgen=3000; // peak output of soalr PV system in W – used to calculate when to change cloud icon to a sun
const int PV_gen_offset=50; // When generation drops below this level generation will be set to zero – used to force generation level to zero at night
//////———————————————————–

//// Sampling
int numberOfSamples = 3000;
//Enter the values of your setup below
// Voltage is reduced both by wall xfmr & voltage divider
#define AC_WALL_VOLTAGE 230.0
#define AC_ADAPTER_VOLTAGE 10.5
// Ratio of the voltage divider in the circuit
#define AC_VOLTAGE_DIV_RATIO 10
// CT: Voltage depends on current, burden resistor, and turns
#define CT_BURDEN_RESISTOR 33
#define CT_TURNS 2000
#define ADC_COUNTS (1<<ADC_BITS)
#if defined(__arm__)
#define ADC_BITS 12
#else
#define ADC_BITS 10
#endif
//////———————————————————–

//// Calibration coeficients
//These need to be set in order to obtain accurate results
//Set the above values first and then calibrate futher using normal calibration method described on how to build it page.
double VCAL = 1.00;
double ICAL = 1.00;//0.99;
double PHASECAL = 2.3;//1.7;//2.5
// Initial gueses for ratios, modified by VCAL/ICAL tweaks
double I_RATIO = (long double)CT_TURNS / CT_BURDEN_RESISTOR * 5 / 1024 * ICAL;
int lastSampleV,sampleV; //sample_ holds the raw analog read value, lastSample_ holds the last sample
int lastSampleI,lastSampleI2,sampleI,sampleI2;
double lastFilteredV,filteredV; //Filtered_ is the raw analog value minus the DC offset
double lastFilteredI,lastFilteredI2,filteredI,filteredI2;
//Stores the phase calibrated instantaneous voltage.
double shiftedV;
double phaseShiftedV; //Holds the calibrated phase shifted voltage.
double sqV,sumV,sqI,sqI2,sumI,sumI2,instP,instP2,sumP,sumP2; //sq = squared, sum = Sum, inst = instantaneous
//Calibration coeficients
double VAC = 230.0;
long readVcc();
//Useful value variables
double realPower,
realPower2,
apparentPower,
apparentPower2,
powerFactor,
powerFactor2,
Vrms,
/*Vrms2,*/
Irms,
Irms2;
int startV; //Instantaneous voltage at start of sample window.
boolean lastVCross,checkVCross; //Used to measure number of times threshold is crossed.
int crossCount,crossCount2;
//////———————————————————–

//// FREQUENCY MEASURMENT VARIABLES—————————
unsigned long vLastZeroMsec; //time in microseconds when the voltage waveform last crossed zero.
unsigned long vPeriod; //Micro seconds since last zero-crossing
unsigned long vPeriodSum; //Sum of vPeriod’s to obtain an average.
unsigned long vPeriodCount; //Number of periods summed
float freq; //Frequency
//Used to filter out fringe vPeriod readings.
unsigned long expPeriod = 20000; //Configured for 50Hz 20000 //- If your 60Hz set expPeriod = 16666
unsigned long filterWidth = 2000;
int n;
//////———————————————————–

#define NETTIMECHECK 120
long netTimeout = 0; // counter to check for net activity
//// analog in and filter
long VCCread=0;
long readVcc() {
// call: readVcc();
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
// delay(100);
}
double V_RATIO; // for use after calibration KLL
//////———————————————————–

//// ———— Init connec réseau local
//byte ip[] = { 192, 168, 1, 111 }; //Manual setup only
IPAddress ip(192,168,1,111);
byte gateway[] = { 192, 168, 1, 1 }; //Manual setup only
byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer server = EthernetServer(80); //port 80
//////———————————————————–

const int MAX_PAGENAME_LEN = 8; // max characters in page name
char buffer[MAX_PAGENAME_LEN+1]; // additional character for terminating null

void setup()
{
msTick=millis(); // Initialise the msTick counter
// initialisation du port série sur broches 0-1 : 1200,7,E,1 pour connexion téléinfo
//// Serial & Web init
//Serial.begin(115200); // réinitialise communication série
Ethernet.begin(mac, ip, gateway, subnet); //for manual setup
server.begin();
// Wire.begin();
//////———————————————————–

// Set the clock to run-mode, and disable the write protection
// setup 1302
Time t = rtc.time();
snprintf(buf, sizeof(buf), « DS1302 time: %02d:%02d:%02d »,
t.hr, t.min, t.sec);
//////———————————————————–

//// Pulse count
/*Initialize INT0 for accepting interrupts */
PORTD |= 0x04;
DDRD &=~ 0x04;
pinMode(LEDPIN, OUTPUT);
//Enable interrupt for light sensor on Digital 3
attachInterrupt(1, Pulse, FALLING);
//////———————————————————–

//analogReference(INTERNAL);
netTimeout = millis(); // timer to make sure the net is active

}

void Pulse() // routine called when light sensor interrupt is triggered
{
//pulseFlag = 0;
detachInterrupt(0);
//int pulseState = digitalRead(PORTD);
//if (pulseState > 0) {
pulseFlag = 1;
pulseCount = 1;
//}
}

void loop()
{
uint16_t plen, dat_p;
delay(1000);
VCCread=readVcc(); // calibrate on Vcc in millivolt
V_RATIO = AC_WALL_VOLTAGE / AC_ADAPTER_VOLTAGE * AC_VOLTAGE_DIV_RATIO * VCCread / 1024.0 * VCAL / 1000.0;
I_RATIO = CT_TURNS / CT_BURDEN_RESISTOR * VCCread / 1024.0 * ICAL / 1000.0;
for (int n=0; n<numberOfSamples; n++)
{
//Used for offset removal
lastSampleV=sampleV;
lastSampleI=sampleI;
lastSampleI2=sampleI2;
//Read in voltage and current samples.
sampleV = analogRead(inPinV);
sampleI = analogRead(inPinI);
sampleI2 = analogRead(inPinI2);
//Used for offset removal
lastFilteredV = filteredV;
lastFilteredI = filteredI; //kll
lastFilteredI2 = filteredI2; //kll
//Digital high pass filters to remove 2.5V DC offset.
filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV);
//filteredV = sampleV – 512; // mod KLL
filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);
filteredI2 = 0.996*(lastFilteredI2+sampleI2-lastSampleI2);
//filteredI = sampleI – 512; // mod KLL
//Phase calibration goes here.
shiftedV = lastFilteredV + PHASECAL * (filteredV – lastFilteredV);
//Root-mean-square method voltage
//1) square voltage values
sqV= filteredV * filteredV;
//2) sum
sumV += sqV;
//Root-mean-square method current
//1) square current values
sqI = filteredI * filteredI;
sqI2 = filteredI2 * filteredI2;
//2) sum
sumI += sqI;
sumI2 += sqI2;
//Instantaneous Power
instP = shiftedV * filteredI;
instP2 = shiftedV * filteredI2;
//Sum
sumP +=instP;
sumP2 +=instP2;

////–FREQUENCY MEASURMENT—————————
if (n==0) vLastZeroMsec = micros();
//Check for zero crossing from less than zero to more than zero
if (lastFilteredV < 0 && filteredV >= 0 && n>1)
{
vPeriod = micros() – vLastZeroMsec; //period of voltage waveform
//Filteres out any erronous period measurments
//Increases accuracy considerably
if (vPeriod > (expPeriod-filterWidth) && vPeriod<(expPeriod+filterWidth))
{
vPeriodSum += vPeriod;
vPeriodCount++;
}
vLastZeroMsec = micros();
} // wave form cross 0
}
//////———————————————————–

//// Calculation of the root of the mean of the voltage and current squared (rms)
//Calibration coeficients applied.
/* double V_RATIO = VCAL *((5000/1000.0) / (ADC_COUNTS));// supply voltage: 5000=5v;3300=3,3v
double I_RATIO = ICAL *((5000/1000.0) / (ADC_COUNTS));*/
Vrms = V_RATIO*sqrt(sumV / numberOfSamples);
Irms = I_RATIO*sqrt(sumI / numberOfSamples);
Irms2 = I_RATIO*sqrt(sumI2 / numberOfSamples);
//Calculation power values
realPower = V_RATIO*I_RATIO*sumP / numberOfSamples;
realPower2 = V_RATIO*I_RATIO*sumP2 / numberOfSamples;
apparentPower = Vrms * Irms;
apparentPower2 = Vrms * Irms2;
powerFactor = apparentPower / realPower;
powerFactor2 = apparentPower2 / realPower2;// / apparentPower2;
//////———————————————————–

//// FREQUENCY CALCULATION————————–
freq = (1000000.0 * vPeriodCount) / vPeriodSum;
vPeriodSum=0;
vPeriodCount=0;
//////———————————————————–
//// Go to the web page
//Serial.println();
EthernetClient client = server.available();
if (client)
{
String readString = String(30);
while (client.connected())
{
if (client.available())
{
// if you’ve gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
char c = client.read();//6
if (readString.length() < 30){//lenreadstr) readString += c; //créé le message reçu
readString += c;
}
if (c == ‘\n’) { //teste que le message reçu est complet
if (readString.indexOf(« cmd=1 ») >0)
{

//// Téléinfo
client.println(F(« HTTP/1.1 200 OK »));
client.println(F(« Content-Type: text/html « ));
client.println(F(« Connection: close »)); // indique au client que la connexion est fermée après réponse
// à noter que la connexion est persistante par défaut coté client en l’absence de cette ligne
client.println(); // ligne blanche obligatoire après l’entete HTTP envoyée par le serveur
client.println(F(« <html><head><title></title></head><body> »));

client.println(F(« </body> »));
client.println(F(« </html> »));

delay(5000); // give the web browser time to receive the data
client.stop(); // close the connection:
break;
}//no ;
else if (readString.indexOf(« cmd=0 ») || !readString)
{
//client.print(F(« GET /?cmd= »));
//client.print(F(« 0 »));
client.println(F(« HTTP/1.1 200 OK »));
client.println(F(« Content-Type: text/html « ));
client.println(F(« Connection: close »)); // indique au client que la connexion est fermée après réponse
// à noter que la connexion est persistante par défaut coté client en l’absence de cette ligne
client.println(); // ligne blanche obligatoire après l’entete HTTP envoyée par le serveur
client.println(F(« <!DOCTYPE HTML><html><head><meta content=’text/html; charset=UTF-8’http-equi »
« v=’content-type’><META HTTP-EQUIV=’Refresh’ CONTENT=’60’; URL=’#’></head><bod »
« y><meta name=’HandheldFriendly’ content=’True’><meta name=’MobileOptimized’  »
« content=’320′><meta name=’viewport’ content=’user-scalable=no, width=device- »
« width, initial-scale=1.0, minimum-scale=1.0 maximum-scale=1.0′><meta http-eq »
« uiv=’cleartype’ content=’on’><meta name = ‘format-detection’ content = ‘tele »
« phone=no’><meta name=’apple-mobile-web-app-capable’ content=’yes’><meta name »
« =’apple-mobile-web-app-status-bar-style’ content=’black’><meta name=’apple-m »
« obile-web-app-title’ content=’ASFDuino’><style type=’text/css’>a {text-decor »
« ation: none;}font {font-family: Arial, Helvetica, sans-serif;}</style><title »
« >Serveur Web Arduido</title> »));

client.print(F(« </head><body bgcolor=’#707274′ style=’margin-top:-17px;margin-left:-2px;’><p »
 » align=’left’><table width=’320′ align=’top’ border=’0′><tr><td width=' »
« 320′ height=’80’ style=’padding: 3px;background: #EBEBEB;border: 2px solid # »
« F5F5F5;border-radius: 11px;-moz-border-radius: 11px;-webkit-border-radius: 1 »
« 1px;box-shadow: inset 0px 0px 9px 1px rgba(119, 119, 119, 0.44);-moz-box-sha »
« dow: inset 0px 0px 9px 1px rgba(119, 119, 119, 0.44);-webkit-box-shadow: ins »
« et 0px 0px 9px 1px rgba(119, 119, 119, 0.44);line-height: 12px;’><div style= »
« ‘text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.87);color: #0080ff;font-size: 16px »
« ;’><center><b>SERVEUR HTTP embarqu&eacute; sur carte Arduino&copy;</b></cent »
« er></div><br><center><font size=’1′ color=’Black’><b>Acc&egrave;s via liaison »
 » ETHERNET</b><br><font size=’-1′><a href=’http://%5Byourserver%5D&rsquo; target=’_blank’>{nameofyourserver]</a></font></center></font><hr align=center width =90%/><font size=’1′ col »
« or=’Black’><center><b>Monitoring Compteur ErDF &  »
« Panneaux solaires<br>Drink your coffee easy!</b></center></font><hr align=cent »
« er width =90%/></td></tr><tr><td height=’400′ style=’padding: 3px;b »
« ackground: #EBEBEB;border: 2px solid #F5F5F5;border-radius: 11px;-moz-border »
« -radius: 11px;-webkit-border-radius: 11px;box-shadow: inset 0px 0px 9px 1px  »
« rgba(119, 119, 119, 0.44);-moz-box-shadow: inset 0px 0px 9px 1px rgba(119, 1 »
« 19, 119, 0.44);-webkit-box-shadow: inset 0px 0px 9px 1px rgba(119, 119, 119, »
 » 0.44);’> »));
memset(buffer,0, sizeof(buffer)); // clear the buffer

//// RTC part

// Get the current time and date from the chip
Time t = rtc.time();
second=t.sec;
minute=t.min;
hour=t.hr;
///////
client.print(F(« <center> »));
client.print(hour);
client.print(F(« : »));
if (minute < 10)
{
client.print(« 0 »),client.print(minute);
}else{
if (minute == 60){
client.print(F(« 00 »));
}else{
client.print(minute);
}
}
client.print(F(« </center> »));
// client.print(kwh);
// client.println(F( » KWh »);
///////
client.print(F(« <font size=’1′ color=’Black’><u>Production PV:</u> »));
if (realPower < 100.00)
{
client.print(F(« <div style=’position: absolute; center: 138px; width: 418px; height: 20px;’><div style=’display: inline;’>Etat PV: </div><div style=’display: inline;color: red;’>Off</div> <div style=’display: inline;’> >Panne< ou >Nuit< </div></div> »));
// client.println(F(« <br><br />Intensité: 0.00 <b>A</b><br />Puissance réelle: 0.00 W</b><br />Puissa »
// « nce apparente: 0.00 <b>VA</b><br />Facteur de puissance: 0.00 <b>%</b><br /> »
// « <u>Consommation ErDF:</u> »));
}
else {
client.print(F(« <div style=’position: absolute; center: 138px; width: 418px; height: 20px;’><div style=’display: inline;’>Etat PV: </div><div style=’display: inline;color: green;’>On</div></div> »));
}
client.print(F(« <br><br />Intensité: <font style=’color: blue;’> »));
client.print(Irms);
client.print(F( » </font><b>A</b><br />Puissance réelle: <font style=’color: blue;’> »));
client.print(realPower);
client.print(F( » </font><b>W</b><br />Puissance apparente: <font style=’color: blue;’> »));
client.print(apparentPower);
client.print(F( » </font><b>VA</b><br />Facteur de puissance: <font style=’color: blue;’> »));
client.print(powerFactor2);
client.print(F( » </font><b>%</b><br /><u>Consommation ErDF:</u> »));
client.print(F(« <br />Intensité2: <font style=’color: blue;’> »));
client.print(Irms2);
client.print(F( » </font><b>A</b><br />Puissance réelle 2: <font style=’color: blue;’> »));
client.print(realPower2);
client.print(F( » </font><b>W</b><br />Puissance apparente 2: <font style=’color: blue;’> »));
client.print(apparentPower2);
client.print(F( » </font><b>VA</b><br />Facteur de puissance 2: <font style=’color: blue;’> »));
client.print(powerFactor2);
client.print(F( » </font><b>%</b><br />Différenciel PV/ErDF: <font style=’color: blue;’> »));
if (realPower < 100.00)
{
client.print(realPower – realPower2);
client.print(F( » </font><b>W</b> »));
}
else {
client.print(realPower – realPower2);
client.print(F( » </font><b>W</b><br />Ratio: <font style=’color: blue;’> »));
client.print(2900.00 / realPower);
client.print(F( » </font><b>%</b> »));
}
client.print(F(« <br /><u>Divers:</u><br />Tension secteur: <font style=’color: blue;’> »));
client.print(Vrms + AC_ADAPTER_VOLTAGE);
client.print(F( » </font><b>V</b><br /> »));
client.print(F(« Fréquence réseau: <font style=’color: blue;’> »));
client.print(freq);
client.print(F( » </font><b>Hz</b><br />Sensor1: « ));
// client.println(prt,1);
client.print(F(« <br />Sensor2: « ));
// client.println(prt,2);
//// Pulse count
if (pulseFlag == 1)
{
pulseCount ++;
// pulseFlag = 0;
client.print(« <br />Impulsions: <font style=’color: blue;’> »);
client.print(pulseCount);
client.print(F( » </font>pulse en « ));
client.print(millis());
client.print(F( » ms »));
delay(10);
attachInterrupt(0, Pulse, LOW);
}
else{
client.print(« <br />Impulsions: <font style=’color: blue;’> »);
client.print(pulseCount);
client.print(F( » </font>pulse depuis « ));
client.print(millis()/100);
client.print(F( » s »));
}
//////

//// KWh prod
if ((millis()-fast_update)>200)
{
fast_update = millis();
//DateTime

// int last_hour = hour;
// char nowhour = rtc.hour();
// char nowminute = rtc.minute();

if (realPower < 100.00)
{
if (realPower2 < 100.00)
{
usekwh = 0.00;
usewh = 0.00;
genkwh = 0.00;
genwh = 0.00;
}
else{
usekwh += (realPower2 * 0.2) / 3600000;
usewh += usekwh * 1000;
genkwh = 0.00;
genwh = 0.00;
}
}
else{
// if (SolarPV_type==1){
usekwh += (realPower2 * 0.2) / 3600000;
usewh += usekwh * 1000;
genkwh += (realPower * 0.2) / 3600000;
genwh += genkwh * 1000;
// }
}
// if (SolarPV_type==2){
// usekwh += ((realPower2 + realPower) * 0.2) / 3600000;
// usewh += usekwh * 1000;
// genkwh += (realPower * 0.2) / 3600000;
// genwh += genkwh * 1000;
// }

if (last_hour == 23 && hour == 00)
{
int i;
for (i=6; i>0; i–) gen_history[i] = gen_history[i-1];
genkwh = 0;
genwh = 0;
for(i=6; i>0; i–) use_history[i] = use_history[i-1];
usekwh = 0;
usewh = 0;

}
gen_history[0] = genkwh;
use_history[0] = usekwh;

// if (SolarPV_type==1){
cval_use = cval_use + (realPower2 – cval_use)*0.50;
cval_gen = cval_gen + (realPower – cval_gen)*0.50;
// }

// if (SolarPV_type==2){
// cval_use = cval_use + ((realPower2+realPower) – cval_use)*0.50;
// cval_gen = cval_gen + (realPower – cval_gen)*0.50;
// }

if (cval_gen<PV_gen_offset) cval_gen=0; //set generation to zero when generation level drops below a certian level (at night) eg. 20W

//use, usekwh, gen, maxgen, genkwh, temp, mintemp, maxtemp, hour, minute, last_emontx, last_emonbase)
//client.println(cval_use);
client.print(F(« <br />Consommation ErDF: <font style=’color: blue;’> »));
client.print(usekwh);
client.print(F( » </font>KWh (<font style=’color: blue;’> »));
client.print(usewh);
client.print(F(« </font> Wh)<br />Production PV: <font style=’color: blue;’> »));
client.print(genkwh);
client.print(F(« </font> KWh (<font style=’color: blue;’> »));
client.print(genwh);
client.print(F(« </font> Wh)<br /> »));
//client.println(temp);
//client.print(F( » | « ));
//client.println(mintemp);
//client.print(F( » | « ));
//client.println(maxtemp);
//client.print(F( » | « ));

// client.print(kwh);
// client.println(F( » KWh »);
client.print(F(« </font></td></tr></table></p> »));//<form method=’GET’><input type=’hidden’ name=’cmd’ value=’teleinfo’ /><input type=’submit’ value=’Téléinfo’ /></form></td></tr></table></p> »));
client.print(F(« <p style=’display: none;’>INSERT INTO enerduino VALUES (‘ »));//(id, h, min, irmspv, rppv, appv, pfpv, irmsedf, rpedf, apedf, pfedf, ratio, u, f, pc, usepw, genpw, s1, s2, rawti)
client.print(F(« ‘, ‘ »));
client.print(hour);
client.print(F(« ‘, ‘ »));
if (minute < 10){
client.print(F(« 0 »)),client.print(minute);
}else{
if (minute == 60){
client.print(F(« 00 »));
}else{
client.print(minute);
}
}
client.print(F(« ‘, ‘ »));
client.print(Irms);
client.print(F(« ‘, ‘ »));
client.print(realPower);
client.print(F(« ‘, ‘ »));
client.print(apparentPower);
client.print(F(« ‘, ‘ »));
client.print(powerFactor);
client.print(F(« ‘, ‘ »));
client.print(Irms2);
client.print(F(« ‘, ‘ »));
client.print(realPower2);
client.print(F(« ‘, ‘ »));
client.print(apparentPower2);
client.print(F(« ‘, ‘ »));
client.print(powerFactor2);
client.print(F(« ‘, ‘ »));
client.print(2900/realPower);
client.print(F(« ‘, ‘ »));
client.print(Vrms + AC_ADAPTER_VOLTAGE);
client.print(F(« ‘, ‘ »));
client.print(freq);
client.print(F(« ‘, ‘ »));
client.print(pulseCount);
client.print(F(« ‘, ‘ »));
client.print(usekwh);
client.print(F(« ‘, ‘ »));
client.print(genkwh);
client.print(F(« ‘, ‘0’, ‘0’, ‘0’)</p> »));
// client.print(F(« 0 »));
// client.print(F(« ‘)</p> »)); // message debug Terminal Arduino
//////——————————————————-
client.print(F(« </body></html> »));
readString = «  »;
break;
}//if milli
}//if clcmd 1 ou 0
}//if c
//////————————————————————————-
}//if clientav
///////
}//while clientcon
delay(10000); // give the web browser time to receive the data
client.stop(); // close the connection:
}//if client
//Reset accumulators
sumV = 0;
sumI = 0;
sumP = 0;
// sumV2 = 0;
sumI2 = 0;
sumP2 = 0;
delay(10);
//////———————————————————–
}
void printP(const prog_uchar *str)
{
EthernetClient client = server.available();
// copy data out of program memory into local storage, write out in
// chunks of 32 bytes to avoid extra short TCP/IP packets
// from webduino library Copyright 2009 Ben Combee, Ran Talbott
uint8_t buffer[32];
size_t bufferEnd = 0;

while (buffer[bufferEnd++] = pgm_read_byte(str++))
{
if (bufferEnd == 32)
{
client.write(buffer, 32);
bufferEnd = 0;
}
}

// write out everything left but trailing NUL
if (bufferEnd > 1)
client.write(buffer, bufferEnd – 1);
}


Le retour d’expé de l’article Régulateur d’alternateur réparé:
Après un remontage relativement simple, contrôle et mise en route du moteur, le nouveau transistor Darlington fait son job et l’icône batterie orange n’apparait plus.
Peut-être un petit peu fainéant à bas régime mais efficace au premier petit coup d’accélérateur, la tension reste constante au ralenti avec 13.4V, 13.7V en accéléré puis 13.5v avec phares et ventilation en fonction.
Pas d’échauffement après un aller/retour sur 2km, absolument pas déçu de ma répa.
Désormais, je garde ce régu qui recevra des charbons neufs la prochaine fois qu’ils seront usés (y’a le temps!).
Quelques photos du régu modifié avant fermeture par capsule du côté composants…
Ci dessous la vue côté composants, en haut à droite du circuit, l’emplacement du défunt Darlington MJD127 en SOT-223 où ressortent les 3 fils qui vont au nouveau Darlington BDX54 (préférence) ou BDW94C (je n’avais plus que ça en stock)
20191101_203754
Je ne l’ai pas fait mais vous pouvez mettre une touche de vernis tropicalisant sur les soudures et même sur le circuit (à condition qu’il soit bien nettoyé du silicone d’origine). Le collecteur qui sert aussi de fixation du boitier doit être isolé du petit refroidisseur avec un isolant silicone toilé et une entretoise d’isolation sur la vis.
20191101_203804
Bon, vrai que j’aurais pu connecter les fils directement du côté composants au lieu de percer le sandwich CI/refroidisseur mais bon… Du moment que vous pouvez remettre le capot plastique du cul d’alterno…
20191101_203815.jpg


Face au coût moyennement élevé d’un régulateur d’alternateur neuf, celui de mon espace 3 sur alternateur de 110A avait lâché.
Curieux de connaitre son fonctionnement, j’ai donc tenté d’accéder au circuit interne, ayant la chance d’en avoir un en cms sur circuit collé à un refroidisseur et non pas en capsule genre TO3 et circuit noyé dans une résine impossible à enlever, j’ai donc pu enlever le silicone noir recouvrant un autre silicone cristal recouvrant le circuit.
Parfait.
Après nettoyage, prise de mesure des différents composants et le darlington s’occupant d’alimenter le bobinage du rotor était hs.
Une chance, marquage sur le boitier.
J’ai donc tout modifié, retiré l’ancien transistor, et monté en isolé un darlington plus costaud sur un refroidisseur externe.
Après test sur un autre alternateur sur mon établi dont la rotation fût faite en prise directe avec un embout torx dans le mandrin de ma perçeuse à colonne, une batterie, une lampe témoin, un multimètre, ma modification fût concluante.
Reste à monter le régulateur moded sur mon espace et tester…
Par contre, j’ai reporté le schéma et les valeurs de composants sous Eagle.
Le schéma en taille réelle peut être fourni sur simple demande…
Reg altern Espace3 schem mini
Reg altern Espace3
(suite: Retour d’expé)


mint173-mate-desktop
Simple, rapide, facile d’install, peu gourmand, des repo sans erreurs, efficace quant à sa sécu et sa config d’optimisation/perso.
Un live usb par LinuxLive USB Creator => un hdd même pas formaté et avec plein de trucs dedans => installé en faisant sa place sans rien toucher autour => boot rapide et une utilisation immédiate en mode stock.
Ce que j’aime linux et le free!
Je me permet d’ailleurs de poser ici un lien sur le blog d’un pote free addict, testeur à ses heures, expérimenté, lequel reste bien plus intéressant à lire et vous propose ses tests où vous pourrez vous faire vos avis…
leblogdolivyeahh – Distributions pour Débutants: Linux Mint


J’ai lu sur pistonheads.com un gars appelé salgar qui avait utilisé un Raspberry Pi pour lire les données de sa moto via un lecteur USB OBD-II et j’ai pensé essayer ça sur voiture.

91zSu44+34L._SX466_
OBD ou On Board Diagnostics et OBD-II sont des standards pour la communication et la lecture de données depuis une voiture, standard sur la plupart des voitures modernes et vous avez probablement un connecteur dans votre voiture (après 2000) qui vous permet de lire toutes sortes de données comme régime, vitesse, température et un million d’autres choses.

8BYSsLF

Mise à jour – J’ai amené ce prototype à l’étape suivante et utilisé les données OBD pour surveiller la vitesse, la rotation moteur, la température et la position du papillon des gaz.

J’ai un câble d’interface USB vers OBD2 pour environ 20€. Choisissez-en un sur Priceminister ou Ebay.

usb obd
J’ai ensuite pris un fork du logiciel de salgar dans son dépôt github, https://github.com/roflson/pyobd, comme base de mon programme.
Le logiciel de salgar est un extrait d’un projet appelé pyobd, https://github.com/peterh/pyobd, une application basée sur une interface graphique pour la lecture de données OBD-II.

J’ai utilisé ceci comme base pour un programme qui se connecterait via l’interface OBD-II, «demanderait» à la voiture les capteurs qu’il supportait, puis lisait les capteurs de données en boucle toutes les 0,5 secondes et les écrivait à l’écran.

Je vois cela comme une première étape dans un projet d’enregistrement de données sur une voiture pour d’autres utilisations.

Télécharger et exécuter:
Vous pouvez télécharger le code directement depuis github, https://github.com/martinohanlon/pyobd, alors ouvrez un terminal et suivez les instructions:

sudo apt-get install python-serial
sudo apt-get install git-core
cd ~
git clone https://github.com/martinohanlon/pyobd
cd pyobd
python obd_capture.py

N’hésitez pas à me faire part de vos modifs, ajouts ou autres créations à partir de ce projet…


Tiens, j’avais pas encore publié mon projet de « réplique » de Sojourner commencé il y a 4 ans?
Ben c’est chose faite!
Entre divers projets commencés et publiés ici, pas encore finis par manque de temps, j’ai (enfin) décidé de continuer mon robot, grâce à Arduino qui me facilite grandement la tâche (ardue j’en conviens) au niveau électronique et language de programmation qui, à la base, devait tourner autour des microcontrôleurs PIC et de morceaux de robot Cybot.
Ca y’est, la partie méca étant bien avancée et plus fiable qu’au début du projet ainsi que la carte électronique proto avec le source du programme gérant les moteurs pas à pas bipo et les servomoteurs.
Bon, comme pour le reste, la suite viendra en temps et en heure!
Aller, un aperçu de l’engin fabriqué avec les « moyens du bord »…

Sojourner versus Arduino et DIY...

Sojourner versus Arduino et DIY…

Antisèche MYSQL

Publié: 18/03/2014 dans Programmation
Tags:, ,

Voici une petite anti-sèche des commandes MySQL les plus courantes. On sait jamais, ça peut être utile…
(Surtout pour moi qui ai une ram datant de l’époque mérovingienne…)

CREATE DATABASE `maindb` /*!40100 DEFAULT CHARACTER SET utf8 */;

DROP TABLE IF EXISTS `maindb`.`log`;
CREATE TABLE  `maindb`.`log` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`client` varchar(64) NOT NULL,
`method` varchar(16) NOT NULL,
`component` varchar(32) NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`freetext` varchar(256) NOT NULL,
`ack` enum(’0′,’1′) NOT NULL DEFAULT ’0′,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

INSERT INTO log (client, method, component, freetext)
VALUES (‘Client01′, ‘PS’, ‘COMP01′, “”);

INSERT INTO log (client, method, component, freetext)
VALUES (‘Client01′, ‘SNMP’, ‘COMP01′, ‘No response from localhost’);

SELECT * FROM log;

SELECT * FROM log WHERE ack=’0′;

CREATE VIEW `maindb`.`not_ack` AS
SELECT id, client, method, component, timestamp, freetext FROM log WHERE ack=’0′;

UPDATE log SET ack=’1′ WHERE client=’Client01′;

DELETE FROM log WHERE client=’Client01′;

SELECT * FROM not_ack;

SELECT * FROM maindb.log WHERE DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 2 HOUR) <= timestamp;

DELETE FROM maindb.log WHERE (DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY) > timestamp) AND (ack=’1′);

Procédures et fonctions stockées

Procédure:

DELIMITER $$

DROP PROCEDURE IF EXISTS `maindb`.`CLEAN_OLD_ACK` $$
CREATE PROCEDURE `maindb`.`CLEAN_OLD_ACK` ()
BEGIN
DELETE FROM maindb.log
WHERE (DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY) > timestamp)
AND (ack=’1′);
END $$

DELIMITER ;

Procédure renvoyant une valeur passée en paramètre:

DELIMITER $$

DROP PROCEDURE IF EXISTS `maindb`.`NBALERTS` $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `NBALERTS`(OUT result BIGINT)
BEGIN
SELECT COUNT(*) INTO result FROM log;
END $$

DELIMITER ;

On peut l’utiliser ainsi:

CALL NBALERTS(@a);
SELECT @a;

Procédure utilisant une variable utilisateur:

SELECT value INTO @age FROM config WHERE token=’age_purge’ LIMIT 1;
SELECT * FROM log WHERE (UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(timestamp) > (86400*@age));

Fonction:

DELIMITER $$

DROP FUNCTION IF EXISTS `maindb`.`bonjour` $$
CREATE FUNCTION `maindb`.`bonjour` (s CHAR(20)) RETURNS CHAR(50)
BEGIN
RETURN CONCAT(‘Bonjour, ‘,s,’!’);
END $$

DELIMITER ;

Elle peut s’utiliser ainsi:

SELECT bonjour(‘moi’);

Création de vue:

select
`maindb`.`user`.`Id` AS `id_user`,
concat(`maindb`.`user`.`prenom`,’ ‘,`maindb`.`user`.`nom`,’ (‘,`maindb`.`user`.`pseudo`,’)’) AS `nom`,
`maindb`.`user_objet`.`objet` AS `objet`
from (`maindb`.`user` left join `maindb`.`user_objet` on((`maindb`.`user`.`Id` = `maindb`.`user_objet`.`id_user`)))

Client MySQL en C#

Vous aurez besoin du connecteur MySQL .NET, disponible sur le site de MySQL.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using MySql.Data.MySqlClient;

namespace mysql
{
class MySQLConnector
{
private MySqlConnection ConnectionRessource;
private string DBName;
private string Server;
private string Login;
private string Password;
private Boolean dbUp;
private string connectionString;

private string requete;
private MySqlCommand com;
private MySqlDataReader dr;

public MySQLConnector()
{
this.DBName = “testdb”;
this.Server = “localhost”;
this.Login = “root”;
this.Password = “pass”;
this.dbUp = false;
this.connectionString = “Server=” + this.Server + “;” +
“Database=” + this.DBName + “;” +
“User ID=” + this.Login + “;” +
“Password=” + this.Password + “;”;
try
{
ConnectionRessource = new MySqlConnection(connectionString);
ConnectionRessource.Open();
this.dbUp = true;
}
catch(MySqlException e)
{
System.Console.Out.WriteLine(e.Message);
}
}

public void Close()
{
try
{
ConnectionRessource.Close();
}
catch (MySqlException e)
{
System.Console.Out.WriteLine(e.Message);
}
}

public void test()
{
requete = “SELECT * FROM table”;
com=new MySqlCommand(requete,ConnectionRessource);
dr = com.ExecuteReader();
while(dr.Read())
{
for(int i=0;i<dr.FieldCount;i++)
{
System.Console.Out.Write(dr.GetValue(i)+” “);
}
System.Console.Out.WriteLine(“”);
}
}
}
}


Avant de poursuivre la construction de mon rover, copie du rover Sojourner qui avait ouvert la voie aux autres rovers sur Mars, je vais construire mon drone quadrimoteur à base d’Arduino et d’éléments de récupération.

Sur la base de ce que l’on peut trouver ça et là sur le net, entre les modèles en kit, les modèles assemblés en vente « prêt à jouer », les modèles fabriqués par imprimante 3D ou les modèles « maison », j’ai glané toutes les infos qui m’étaient nécessaires un peu sur tous ces sites et modèles, et décidé de tout me fabriquer moi même (sauf bien entendu ce que je ne peux faire).

Le but du jeu, quadri-moteur bi-pales, léger, Arduino, auto-stabilisation par gyro et accéléromètre, caméra 2.4ghz, pilotage soit par pc ou soit par radio-commande, autonomie intéressante.

Concernant les moteurs, je vais tester plusieurs méthodes, soit des blocs moteur/pignons/axe/pales de petit hélico Picooz, soit des moteurs spindle de lecteur cdrom avec pales de Picooz, soit des moteurs brushless RC avec pales RC.

Pareil, pour les pales, je vais essayer soit le  bipale de Picooz, soit un bipale acheté en magasin RC, soit un octuple pales de ventilateur de pc de 20cm de diamètre.

J’ai déjà commencé l’assemblage des quatre bras et du boitier qui recevra l’électronique.

_MG_6021<=Vue sur l’assemblage des bras sur une grille métallique de ventilateur de pc

 

_MG_6022<=Détail sur la découpe et l’ajustage des bouts de cornière alu

 

_MG_6023<=Rendu final du tout assemblé

 

C’est tout pour l’instant…
Prochaine étape, pré-assemblage de l’électronique et test des différents moteurs avec Arduino.

MEILLEURS VOEUX 2014!

Publié: 04/01/2014 dans Electronique

Meilleurs voeux 2014 !!!

Meilleurs voeux 2014 !!!


Voilà, après une tentative échouée sur une SPC900 et grillé le capteur ccd, je me suis rabattu sur une Toucam pro II (840k) avec le même capteur, un ICX098BQ.

Le mode opératoire de modifications reste le même que la première idée avec la SPC900, déport du capteur CCD, refroidissement avec module Peltier 25w, mise en boitier hermétique, obturateur électromécanique, modification longue pose, modification de l’amplificateur.

Finalement, concernant le logiciel de gestion de la cam, je préfère rester avec la Toucam pro II, bien plus complet que celui de la SPC900, même si nos logiciels d’astro sont là pour prendre le relais.

Par ailleur, WcCtrl et WcRmac ont été super utiles pour basculer en mode RAW couleur et sauvegarder les paramètres de l’eeprom en local.

Acta non verba où des photos des étapes du travail effectué viennent ci-dessous:

Installation de la calle

Installation du joint caoutchouc

Pose du capteur CCD

Pose du doigt caloporteur sur le CCD, récupéré sur un vieux camcorder VHS CANON, et fixation par vis sur un porte objectif de récupération. Silicon thermique entre le CCD et le doigt

Vérification et centrage du capteur dans le porte objectif et marquage de la broche 1, avant serrage

Soudage des broches du CCD sur une nappe récupérée sur un vieux camcorder VHS Panasonic

Itou que l’image précédente

Fixation du doigt caloporteur sur un radiateur de chipset de carte mère PC, des écrous sont bloqués dans les ailettes et tiennent vraiment bien. Après serrage, les écrous remontent légèrement et permettent le plaquage du doigt caloporteur contre le refroidisseur alu, avec silcon thermique entre

Pliage des nappes en préparation à blanc

Soudage des nappes sur des connecteurs récupérés je ne sais où, mais bien pratique en cas de démontage de la carte électronique! La vue horrible de certaines modifs de webcam que j’ai pu trouver sur le net m’a imposée d’ajouter des connecteurs au lieu de souder à l’arrache (et parfois avec d’horribles fils trop gros!) sur la carte électronique. Faut pas être boeuf!!!

J’aurai pu prendre les connecteurs de nappe trouvés avec les nappes mais tout était déjà prêt venant de la SPC900 et si j’aurais besoin, à la suite, de connecter je ne sais quoi sur une des broches allant au capteur CCD, ben c’est là…

Nota bene une broche vide sur chaque nappe, qui me serviront à connecter une thermistance ou un capteur I2C pour mesure de température côté CCD…

Thermistance soudée et placée contre le CCD

Découpage et usinage d’un bloc de plexi récupéré sur une vieille dalle LCD, qui assurera la rigidité de l’ensemble et l’isolation thermique dans le boitier

Vue sur l’obturateur électromécanique du vieux camcorder VHS CANON ainsi que de la bague de fixation sur le coulant du télescope sur le haut du boitier tout en époxy cuivré double face

Vue intérieur du boitier avec l’obturateur fixé (C’est simple, con, mais ca suffit pour fonctionner…)

On aperçoit en haut à droite de la carte électronique un quadruple NAND TTL en HC pour la modif longue pose qui sera raccordé par la suite à un convertisseur RS232 USB

Après assemblage et connexion de la gestion de ventilo, mise en route de l’ensemble Peltier/ventilo et mesure de température prise directement sur le haut du doigt caloporteur, en effet, ca fonctionne! -6.3°C!!!

Vue sur le fil du capteur de temp du multimètre par l’obturateur, on aperçoit la vitre du CCD légèrement givrée…

Plus près…

Encore plus près, au mieux!!! Petiote précision, par la suite, j’ai monté un disque de verre, récupéré sur une lampe dichroïque 12v de spot, elle est prise en sandwich entre la bague et le boitier, collée par une colle époxy 3M Scotch DP490

Vue sur la carte de gestion du ventilo. Je posterai plus tard le schéma de gestion à base de TL494…

L’ensemble monté sur le coulant du télescope… En attendant des camshoot avant et après refroidissement et modifs, la suite au prochain numéral!