je traine depuis un mois sur le site, mais je viens de remarquer ces deux menus. j'avais jamais vue ou c'est une évolution?
ha les vieux retraité et leur carreaux en bois

petite précision:vu leur prix dérisoire je vais en mettre 20 à 25 pces
combien peut on mettre de sondes
il y a a mon sens deux façon de voir:
a) la limitation électrique
b) le temps de réponse.
pour ce qui est du temps de réponse tout dépend comment a été écrit le logiciel car il semble qu'il y ait deux méthode:
la première:
le programme va à la découverte (commande "search ROM") des sondes du réseau, puis à chaque DS18B20 trouvée lance une conversion, attend (750 ms) et lui demande le résultat. Si on a beaucoup de sondes, la collecte prend du temps (0,8 seconde par sonde), donc la limitation viendra de la partie logicielle.
parade: Si on suppose que le bus 1-wire ne contient que des DS18B20, on peut lancer l'ordre de conversion à toutes les sondes sur le bus ("skip ROM"), et ensuite collecter les températures de toutes les sondes sans attente
mais alors arrive la limite électrique. Deux limites, celle de l' adaptateur et celle du bus USB
la limite électrique du bus:
le bus USB peut fournir 5Volts 500Ma
La consommation maximale d'une sonde DS18B20 est 1,5 mA pendant les écritures EPROM et les conversions.
si l'on soustrait ce que le bus donne déjà (souris)..... on peut connaitre ne nombres de sondes maxi avant d'avoir le message Windows: pic de consommation sur le port USB
la limite électrique de l'adaptateur:
sur le DS9490 on peut tirer jusqu'à 42 mA, mais il est conseillé de rester sous 25 mA. ce qui donne (Si on lance toutes les conversions de température en même temps) entre 17 (limite sûre) et 28 sondes (limite maxi).
toutes correction sera la bienvenue Alain/Juju
Bonjour Alain,
Tu peux demander une résolution sur 11bits au lieu de 12, c'est ce que je fais maintenant et cela fait passer le temps de conversion de 750ms à 375ms.
Tu peux aussi exploiter le mode "skip ROM" mais il faut alimenter ton réseau, ne pas utiliser le mode parasite.
Dans mon cas je ne l'utilise pas car les usagers peuvent avoir un réseau alimenté ou non.
le gros avantage du 1-wire est qu'une fois le bus en place, ajouter une sonde coûte très peu.
Je soude une prise RJ11 sur chaque sonde et j'utilise un "hub" RJ11, en fait un duplicateur de ports RJ11 : il suffit donc de brancher la nouvelle sonde sur le duplicateur.
La collecte 1-wire est plus fiable que la collecte M3, car tous les quelques jours, j'ai un souci sur la collecte
Ci-dessous liens vers mon petit programme C pour manipuler les sondes.
Il utilise les drivers TMEX aussi.
Edition de liens statique donc il doit tourner sur tout PC avec les drivers installés.
L'exécutable (compilé par Visual C++ Express : gratuit), pas de virus a priori : c'est moi Solarihome, pas Alain qu'il l'ait compilé :
http://solarihome.perso.sfr.fr/oneWire/oneWire2.exe
Le programme permet :
1) D'afficher les ROM de tous devices présents sur le bus (option "search")
2) De configurer toutes les sondes DS18B20 à la résolution demandée (option "config" [<pr>])
3) D'afficher le ROM et la température de toutes les sondes DS18B20 présentes sur le bus
4) D'afficher le scratchpad de toutes les sondes DS18B20 présentes sur le bus (permet de vérifier ce qui se trouve dans l'EPROM)
C'est l'option 3 qui t'intéresse (fonction C cmdeTemp) :
- on reset le bus
- on envoie la commande "skip ROM" (tous les devices écoutent)
- on envoie la commande "convert T"
- on attend 750 ms
- puis on lit la température de toutes les sondes à fond
(la fonction C tousDS18B20 applique une fonction à tous les DS18B20 trouvés)
=> Toutes les sondes convertissent et sont lues en moins d'une seconde.
Le programme C est utilisé comme sous-process d'un script Python. Les résultats sont récupérés sur stdout.
Note : on peut facilement dériver un programme qui lit périodiquement des sondes choisies et écrits leur température dans un fichier.
Cordialement,
Thierry
Code : Tout sélectionner
/*--------------------------------------------------------------------------
* Programme qui opère sur un bus 1-wire connecté au PC
* La gestion des erreurs 1-wire est basique (on abandonne si problème)
* Options :
* - temp : lit et écrit sur stdout les ROM id et températures
* de toutes les DS18B20 trouvées : ROMid1 temperature1 ROMid2 temperature2...
* - config <precision> : fixe la résolution EEPROM des sondes DS18B20 trouvées
* - search : retourne le ROM id de tous les devices 1-wire trouvés sur le bus
* - dump : rend le scratchpad des sondes DS18B20 trouvées sur le bus
* Rend 0 si succès, 1 si échec
*
* Nécessite que les drivers Maxim/Dallas TMEX soient installés.
*
* Auteur : T.Streiff 01/2010
* 27/01/10 : correction pour les températures négatives
*
* Compilateur : Microsoft Visual C++ 2008 Express
* --------------------------------------------------------------------------
*/
#include "iBTMEXCW.H"
#include <stdio.h>
// prototypes locaux
void fatal(char *);
#define DS18B20_FAMILY 0x28
// variables globales
uchar buffer[5120]; // buffer 1-wire
long session; // session 1-wire
int rc; // code retour générique
/*----------------------------------------------------------------------
* Ecrit le message d'erreur sur stderr
*/
typedef struct msg
{
int code;
char *msg;
} msgT;
msgT mapping[] =
{
{ -200, "invalid session" },
{ -201, "session non trouvée" },
{ -1, "port non initialise" },
{ -2, "port non existant" },
{ -3, "fonction non existante" },
{ -12, "echec BCOM" },
{ -13, "evenement BCOM" },
{ 0, "" }
};
char *msgErr(code)
{
msgT *m = mapping;
while (m->code)
{
if (m->code == code)
return m->msg;
++m;
}
return "";
}
void erreur(char *texte)
{
char* msg = msgErr(rc);
fprintf(stderr, "Erreur, ");
fprintf(stderr, texte);
fprintf(stderr, " : (%d) %s\n", rc, msg);
}
/*----------------------------------------------------------------------
* Termine le programme
*/
void fin(int diag)
{
#if DEBUG
char *msg;
switch (diag)
{
case EXIT_SUCCESS: msg = "OK"; break;
case EXIT_FAILURE: msg = "echec"; break;
default: msg = "inconnu"; break;
}
fprintf(stderr, "Resultat : %s\n", msg);
#endif
exit(diag);
}
/*----------------------------------------------------------------------
* Affiche l'usage sur stdout et quitte
*/
char* usageMsg[] =
{
"Usage",
" search [alarm] : donne les ROM de tous les devices [en alarme] du bus",
" temp : donne ROM et temperatures des DS18B20 du bus",
" dump : donne ROM et scratchpad des DS18B20 du bus",
" config [<precision>] : configure la precision des DS18B20 du bus (12-bit par défaut)",
NULL
};
void usage(void)
{
char **p = usageMsg;
while (*p)
{
fprintf(stderr, *p);
fprintf(stderr, "\n");
++p;
}
fin(EXIT_FAILURE);
}
/*----------------------------------------------------------------------
* Fait un reset du bus 1-wire
*/
void OWReset(void)
{
rc = TMTouchReset(session);
if ((rc != 1) && (rc != 2))
fatal("TMTouchReset");
}
/*----------------------------------------------------------------------
* Fait un reset et un match ROM sur le device courant
*/
void OWAccess(void)
{
if ((rc = TMAccess(session, buffer)) < 0)
fatal("TMAccess");
}
/*----------------------------------------------------------------------
* Lance une recherche générale sur le bus 1-wire
*/
void OWFirst(void)
{
if ((rc = TMFirst(session, buffer)) < 0)
fatal("TMFirst");
}
/*----------------------------------------------------------------------
* Lance une recherche de devices en alarme sur le bus 1-wire
*/
void OWFirstAlarm(void)
{
if ((rc = TMFirstAlarm(session, buffer)) < 0)
fatal("TMFirstAlarm");
}
/*----------------------------------------------------------------------
* Continue une recherche en cours sur le bus 1-wire
*/
void OWNext(void)
{
if ((rc = TMNext(session, buffer)) < 0)
fatal("TMNext");
}
/*----------------------------------------------------------------------
* Continue une recherche en cours des devices en alarme sur le bus 1-wire
*/
void OWNextAlarm(void)
{
if ((rc = TMNextAlarm(session, buffer)) < 0)
fatal("TMNextAlarm");
}
/*----------------------------------------------------------------------
* Continue une recherche en cours sur le bus 1-wire
*/
void OWRom(short rom[])
{
if ((rc = TMRom(session, buffer, rom)) < 0)
fatal("TMRom");
}
/*----------------------------------------------------------------------
* Lit/écrit un octet sur le bus 1-wire
*/
short OWTouchByte(short byte)
{
if ((rc = TMTouchByte(session, byte)) < 0)
fatal("TMTouchByte");
return rc;
}
/*----------------------------------------------------------------------
* Fixe le niveau du bus 1-wire
*/
short OWLevel(short operation, short levelMode, short primed)
{
if ((rc = TMOneWireLevel(session, operation, levelMode, primed)) < 0)
fatal("TMOneWireLevel");
return rc;
}
/*----------------------------------------------------------------------
* Prépare une recherche de devices par famille
*/
void OWFamilySearchSetup(short family)
{
if ((rc = TMFamilySearchSetup(session, buffer, family)) < 0)
fatal("TMFamilySearchSetup");
}
/*----------------------------------------------------------------------
* Ouvre la session 1-wire
*/
void ouvreSession(void)
{
short portNum, portType;
int preMsg;
char *msg;
// récupère le port
if (TMReadDefaultPort(&portNum, &portType) < 0)
{
rc = 0;
fatal("TMReadDefaultPort : port par defaut non trouve");
}
// attend qu'il soit possible d'ouvrir la session
preMsg = TRUE;
for (;;)
{
rc = TMExtendedStartSession(portNum, portType, NULL);
if (rc < 0)
{
fatal("TMExtendedStartSession");
}
if (rc > 0) break;
if (preMsg)
{
fprintf(stderr, "Une autre application utilise le 1-wire...\n");
preMsg = FALSE;
}
}
session = rc;
// setup du bus 1-wire
rc = TMSetup(session);
if (rc < 0)
fatal("TMSetup");
if (rc == 1) return;
switch (rc)
{
case 0: msg = "echec du setup"; break;
case 2: msg = "setup OK mais bus en court-circuit"; break;
case 3: msg = "setup : le bus 1-wire n'existe pas"; break;
case 4: msg = "TMSetup non supporte"; break;
default: msg = "probleme setup inconnu"; break;
};
fatal(msg);
}
/*----------------------------------------------------------------------
* Ferme la session 1-wire
*/
void fermeSession(void)
{
// ignore le retour
TMEndSession(session);
}
/*----------------------------------------------------------------------
* Ecrit le message d'erreur sur stderr et quitte
*/
void fatal(char *texte)
{
erreur(texte);
fermeSession();
fin(EXIT_FAILURE);
}
/*----------------------------------------------------------------------
* Ecrit le ROM courant dans un fichier (avec un espace derrière)
*/
void ecritRom(FILE *f)
{
short rom[8];
int i;
rom[0] = 0;
OWRom(rom);
for (i=7; i>=0; --i)
fprintf(f, "%02x", rom[i]);
fprintf(f, " ");
}
/*----------------------------------------------------------------------
* Attente de x ms
*/
void attente(ms)
{
ulong t = GetTickCount() + ms;
while (GetTickCount() < t)
TMValidSession(session);
}
/*------------------------------------------------------------------------
* Lit le scratchpad du DS18B20 courant
*/
int litDS18B20(uchar *mem)
{
int i;
uchar CRCByte;
short CRC8;
// sélectionne la sonde courante
OWAccess();
if (rc == 0) return EXIT_FAILURE;
// envoie la commande de lecture mémoire
OWTouchByte(0xbe);
// lit les 8 octets de la mémoire et calcule le CRC
CRC8 = 0;
for (i=0; i<8; ++i)
{
OWTouchByte(0x0ff);
mem[i] = (uchar) rc;
CRC8 = TMCRC(1, &mem[i], CRC8, 0);
}
// lit et contrôle le CRC
OWTouchByte(0x0ff);
CRCByte = (uchar) rc;
if (TMCRC(1, &CRCByte, CRC8, 0) != 0)
{
rc = 0;
erreur("CRC invalide en lisant un scratchpad");
return EXIT_FAILURE;
}
// c'est OK
return EXIT_SUCCESS;
}
/*----------------------------------------------------------------------
* Commande "search"
* écrit sur stdout tous les ROM des devices trouvés sur le bus 1-wire
* si alarm est vrai, sélectionne seulement les devices en alarme
*/
int cmdeSearch(int alarm)
{
ouvreSession();
OWReset();
if (alarm) OWFirstAlarm(); else OWFirst();
OWFirst();
while (rc)
{
ecritRom(stdout);
if (alarm) OWNextAlarm(); else OWNext();
}
fermeSession();
return EXIT_SUCCESS;
}
/*----------------------------------------------------------------------
* Commande "config"
* configure la précision de tous les DS18B20 sur le bus 1-wire
*/
int cmdeConfig(int precision)
{
int config;
ouvreSession();
// calcule l'octet de configuration selon la précision demandée
switch (precision)
{
case 9: config = 0x00; break;
case 10: config = 0x20; break;
case 11: config = 0x40; break;
case 12: config = 0x60; break;
default:
rc = 0;
fatal("precision invalide");
}
// écrit la configuration dans le scratchpad
OWReset();
OWTouchByte(0xcc); // cmd "skip ROM"
OWTouchByte(0x4e); // cmd "write scratchpad"
OWTouchByte(0); // TH (remplissage)
OWTouchByte(0); // TL (remplissage)
OWTouchByte(config); // configuration
// écrit le scratchpad dans l'EEPROM
OWReset();
OWTouchByte(0xcc); // cmd "skip ROM"
OWLevel(LEVEL_SET, LEVEL_STRONG_PULLUP, PRIMED_BYTE); // active le strong pullup
OWTouchByte(0x48); // cmd "copy scratchpad"
attente(10); // attente 10 ms
OWLevel(LEVEL_SET, LEVEL_NORMAL, PRIMED_NONE); // retire le strong pullup
fermeSession();
return EXIT_SUCCESS;
}
/*----------------------------------------------------------------------
* Cherche tous les DS18B20 sur le bus et exécute la fonction pour chacun
*/
void tousDS18B20(void (*fn)())
{
short rom[8];
// initialise la recherche
OWFamilySearchSetup(DS18B20_FAMILY);
for (;;)
{
// cherche le DS18B20 suivant et teste s'il en reste
OWNext();
if (rc == 0) break;
// s'assure que c'est bien un DS18B20
rom[0] = 0;
OWRom(rom);
if (rom[0] != DS18B20_FAMILY) break;
// appelle la fonction à appliquer sur le DS18B20 courant
(*fn)();
}
}
/*----------------------------------------------------------------------
* Affiche le scratchpad du DS18B20 courant
*/
void dumpDS18B20(void)
{
uchar mem[8];
int i;
// lit le scratchpad
if (litDS18B20(mem) != EXIT_SUCCESS)
return;
// affiche le ROM et le scratchpad
ecritRom(stdout);
for (i=0; i<8; ++i)
printf("%02x ", mem[i]);
puts("");
}
/*----------------------------------------------------------------------
* Commande "dump"
* Affiche le scratchpad de tous les DS18B20 sur le bus 1-wire
*/
int cmdeDump(void)
{
// applique la fonction de dump à tous les DS18B20 trouvés
ouvreSession();
tousDS18B20(dumpDS18B20);
fermeSession();
return EXIT_SUCCESS;
}
/*----------------------------------------------------------------------
* Affiche le température du DS18B20 courant
*/
void tempDS18B20(void)
{
uchar mem[8];
float temperature;
int msk;
short temp;
// lit le scratchpad
if (litDS18B20(mem) != EXIT_SUCCESS)
return;
// affiche le ROM
ecritRom(stdout);
// calcule la température selon la précision configurée
// masque les bits non significatifs (le DS ne précise pas qu'ils sont à 0)
switch (mem[4] & 0x60)
{
case 0x00: msk = 0x0f8; break;
case 0x20: msk = 0x0fc; break;
case 0x40: msk = 0x0fe; break;
case 0x60: msk = 0x0ff; break;
default: break; // ne peut pas arriver
}
temp = mem[1] << 8 | (mem[0] & msk);
temperature = (float)(temp * 0.0625);
// affiche la température
printf("%f\n", temperature);
}
/*----------------------------------------------------------------------
* Commande "temp"
* lit la température de tous les DS18B20 sur le bus 1-wire
*/
int cmdeTemp(void)
{
ouvreSession();
// envoie une commande Convert T à tous les DS18B20
// en activant le strong pullup pendant 750 ms
OWReset();
OWTouchByte(0xcc); // cmd "skip ROM"
OWLevel(LEVEL_SET, LEVEL_STRONG_PULLUP, PRIMED_BYTE);// active le strong pullup
OWTouchByte(0x44); // cmd "convert T"
attente(750); // attente 750 ms
OWLevel(LEVEL_SET, LEVEL_NORMAL, PRIMED_NONE); // retire le strong pullup
// lit la température de tous les DS18B20 trouvés
tousDS18B20(tempDS18B20);
fermeSession();
return EXIT_SUCCESS;
}
/*----------------------------------------------------------------------
* Tout commence ici...
*/
void main(int argc, char **argv)
{
int precision;
int alarm;
// vérifie les arguments et appelle la bonne fonction
if (argc == 1)
usage();
// search
if (strcmp(argv[1], "search") == 0)
{
if (argc == 2)
alarm = FALSE;
else
{
if ((argc != 3) || strcmp(argv[2], "alarm") != 0)
usage();
alarm = TRUE;
}
fin(cmdeSearch(alarm));
}
// config <precision>
if (strcmp(argv[1], "config") == 0)
{
if (argc == 2)
precision = 12;
else
{
if ((argc != 3) || (sscanf(argv[2], "%d", &precision) != 1))
usage();
if ((precision < 9) || (precision > 12))
{
rc = 0;
fatal("la precision doit etre entre 9 et 12 bits");
}
}
fin(cmdeConfig(precision));
}
// temp
if (strcmp(argv[1], "temp") == 0)
{
if (argc != 2)
usage();
fin(cmdeTemp());
}
// dump
if (strcmp(argv[1], "dump") == 0)
{
if (argc != 2)
usage();
fin(cmdeDump());
}
// erreur si autre chose
usage();
}
Tout comme sous Vista, par défaut la commande Exécuter n'apparaît pas dans le menu Démarrer de Windows 7.
Il faut taper Exécuter dans Rechercher pour y accéder ou utiliser le raccourci WIN + R
Si l'on veux faire apparaître cette commande de manière permanente dans le menu Démarrer :
- Clic-droit sur la Barre des tâches, puis sélectionner Propriétés.
- Dans l'onglet Menu Démarrer, cliquer sur Personnaliser et cocher Commande Exécuter, puis sur OK et Appliquer.
La commande Exécuter sera dorénavant affichée dans le menu Démarrer (sous Aide et Support).
Le débit du circulateur est estimé par rapport au COP à 7/35°
Débit en m3/h = COP / (deltaT° x 1.163 / puissance consommé kWh
Formule simplifiée du COP immédiat :
COPi = débit x deltaT° x 1.163 / puissance consommée kWh
Voilà, c'est pas compliqué... juste je ne suis pas sûr de bien expliquer.
La puissance est par définition l'énergie divisé par le temps.
Ou l'énergie est la puissance multipliée par le temps.
La puissance est W ou kW.
L'énergie en Wh ou kWh (qui signifie Watt x heure et non Watt par heure)
Si 100 litres d'eau passent avec un delta T de 10°C, ça représente une énergie (en Wh ou kWh) :
100 (litre) x 1,16 (Wh/litre/°C) x 10 (°C) = 1160 Wh
Si cette énergie est passée pendant 1 seconde (parce que le débit est de 100 litres/seconde), alors la puissance est :
1160 (Wh) / 1 = 1160 W
Si la même énergie est passée pendant 10 secondes (parce que le débit est de 10 litres/seconde), la puissance est :
1160 (Wh) / 10 = 116 W
j'utilisais ces formules...
Exemple :
Si j'ai un débit de 400 litres/heure et je mesure un delta T de 15°C.
Pour calculer la puissance :
En 1 heure, l'énergie collectée serait :
400 litres x 1,16 x 15 = 6960 Wh (ce qui veut dire une puissance de 6960 W pendant 1 heure)
donc la puissance instantanée est de 6960 W
Pour l'énergie :
Comme je ne fais des mesures que toutes les minutes, je cumule toutes les minutes la puissance de la dernière minute x 1 minute
Comme on veut des Wh, il faut multiplier par 1/60 (une minute exprimée en heure)
Imaginons qu'on ait la 1ère minute un delta T de 10, la 2ème de 15, puis la 3ème de 10.
La 1ère minute et la 3ème minute, la puissance est de 400 x 1,16 x 10 = 4640 W
La 2ème minute, la puissance est de 6960 W
La 1ère minute, l'énergie est de 4640 / 60 = 77,33 Wh
La 2ème minute, c'est 6960 / 60 = 116 Wh
La 3ème minute, c'est 77,33 Wh comme la 1ère minute
Donc pour les 3 minutes, l'énergie est la somme des 3 nombres, soit environ 271 Wh
Pour ça j'ai un compteur de puissance qui en effet mesure le débit et le delta-t, mais il n'y a rien de prévu pour reprendre ces données et si apparement ton calcul me semble correct, c'est trop complexe (pour moi) de calculer ça en PHP.As tu prévu un graphique de production solaire journalière, afin de savoir combien tu as produit.