Add some fields description

This commit is contained in:
Edward Emelianov 2022-09-20 14:05:23 +03:00
parent 9e152c7c9d
commit b26a4fa173
9 changed files with 8255 additions and 28 deletions

View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.12.3, 2022-07-01T18:37:19. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{7bd84e39-ca37-46d3-be9d-99ebea85bc0d}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">false</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{65a14f9e-e008-4c1b-89df-4eaa4774b6e3}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Big/1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@ -0,0 +1,3 @@
Simple data logger for Hydreon RG-11 rain sensor.

View File

@ -0,0 +1,15 @@
Распиновка:
UART: синий - общий, бело-синий - Tx
Питание: 1 - остальные цветные, 2 - остальные бело-цветные
Подключение через PC18 к CH341:
--|R4k7|--> Ch341 +3.3V
_______ /
Sensor Tx >-o---------|1 4|-----o----------> Ch341 Rx
| | |
|R47k| | PC817 |
| | |
Sensor Gnd >-o-|R330|--|2 3|----------------> Ch341 Gnd
--------

View File

@ -0,0 +1,62 @@
Основные регистры
PeakRS (0..5) похоже на интенсивность осадков. В обычном состоянии болтается около нуля, если
поливать из стакана, показывает 255. При переполнении генерируется флаг PkOverThr.
SPeakRS (0..5) непонятно что. Обычно повторяет PeakRS, но иногда принимает б'ольшие значения.
RainAD8 (64..192) без дождя болтается в районе 170, во время дождя вырастает за 200.
LRA некая кумулятивная величина, которая обычно болтается в районе нуля (до десятка), а при
дожде может сильно возрасти (в зависимости от интенсивности дождя, у меня было свыше 130 в
максимуме). Декремент без дождя (каждые 1-2 секунды).
TransRat (60..170) количество измерений в секунду (???). В обычных условиях в районе 140, при
дожде снижается (у меня было до 90).
AmbLNoise похоже на величину RMS AmbLight.
RGBits Битовые флаги
Флаги RGBits
PkOverThr ==1, если PeakRS зашкаливает (в этом случае значению PeakRS то ли нельзя доверять, то
ли нужно прибавить 256).
Raining ==1 во время дождя (в моем случае дождик был не очень-то активным, поэтому флаг
периодически скакал то в 1, то в 0).
Out1On похоже, что это - флаг переполнения регистра Bucket (после того, как Bucket доходит до
18, он сбрасывается в 0 и устанавливается Out1On на 1 секунду). Позволяет проводить учет
"кумулятивных" осадков.
HtrOn, судя по названию - включение подогрева внутренностей датчика (хотя, зачем это делать
ясным днем - непонятно).
IsDark устанавливается, когда AmbLight==0. На самом деле, это - далеко не темнота (он у меня по
полдня спокойно ==1, если сильно пасмурно).
Cndnstn периодически скачет из 0 в 1 и обратно. Непонятно, что это.
Freeze возможно, указывает на обмерзание датчика.
Storm устанавливается в 1 при LRA>100.
"Медленные" регистры
RevLevel (12) у меня постоянно 14. ХЗ.
EmLevel (30..80) болтается около 40 без дождя, >50 во время дождя. Тоже неизвестно что. Похоже на
корреляцию с RainAD8.
RecEmStr (60..66) у меня болтался в районе 60, достигая минимума в 51 и максимума в 74.
Непонятно, что это. Похоже на корреляцию с RainAD8.
ABLevel (10) обычно 10, но во время дождя болтался от 10 до 12. ХЗ.
TmprtrF (70..100) судя по названию - температура (в Фаренгейтах) внутренностей датчика.
Болталась от 62 до 109. Похоже на правду (этой ночью на горе была вообще адова жара в 19.!).
PUGain (34..39) имело значение 37 (а ранее, когда дома водичкой поливал, - 38). ХЗ.
ClearTR (60..170) болталось от 157 до 160. Дома - от 147 до 150. ХЗ.
AmbLight - условная яркость (очень условная, т.к. 0, как я писал выше, даже в полдень может быть,
если пасмурно).
Bucket кумулятивный счетчик уровня осадков. Эдакий уровень воды в ведре (см. описание флага
Out1On). Инкремент, похоже, по накоплению PeakRS. Декремент без дождя, каждые ~4 часа.
Barrel - кумулятивный счетчик Bucket, инкремент - каждый раз, как Bucket переходит через ~13 после переполнения.
Декремент без дождя, каждые ~2 часа.
RGConfig постоянно в нуле. ХЗ.
DwellT в районе 100, когда дождя нет, спадает до нуля во время дождя. После 100 следующая величина - 50.
Похоже на какую-то экспоненциальную характеристику осадков (без осадков должнобыть 100).
SinceRn счетчик в (условных) минутах после окончания дождя (во время дождя устанавливается в
нуль, затем каждую минуту инкрементируется до 20). В нормальных условиях равен 20.
MonoStb во время сильного дождя уменьшался от 15 до 0 каждую (условную) минуту. На слабые
осадки не реагировал. Подскакивает до 15 каждый раз, как Raining==1.
LightAD (120..136) болтался от 118 до 128. Минимальное значение было во время дождя.
Максимальное - в ясный полдень. Похоже на корреляцию с RainAD8.
RainThr постоянно 12. ХЗ.

View File

@ -42,7 +42,6 @@ static glob_pars G;
static glob_pars const Gdefault = { static glob_pars const Gdefault = {
.device = DEFAULT_DEV, .device = DEFAULT_DEV,
.pidfile = DEFAULT_PIDFILE, .pidfile = DEFAULT_PIDFILE,
.logfile = NULL,
.timeout = 300, // 5 minute timeout .timeout = 300, // 5 minute timeout
}; };
@ -55,6 +54,7 @@ static myoption cmdlnopts[] = {
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")}, {"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
{"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("serial device name (default: )" DEFAULT_DEV ")")}, {"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("serial device name (default: )" DEFAULT_DEV ")")},
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")}, {"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")},
{"outfile", NEED_ARG, NULL, 'o', arg_string, APTR(&G.outfile), _("put output data table into this file (delete existing)")},
{"pidfile", NEED_ARG, NULL, 'p', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")}, {"pidfile", NEED_ARG, NULL, 'p', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
{"timeout", NEED_ARG, NULL, 't', arg_int, APTR(&G.timeout), _("timeout (seconds) to die if no data on input (default: 5min)")}, {"timeout", NEED_ARG, NULL, 't', arg_int, APTR(&G.timeout), _("timeout (seconds) to die if no data on input (default: 5min)")},
end_option end_option

View File

@ -25,6 +25,7 @@ typedef struct{
char *device; // serial device name char *device; // serial device name
char *pidfile; // name of PID file char *pidfile; // name of PID file
char *logfile; // logging to this file char *logfile; // logging to this file
char *outfile; // put output data table into this file
int timeout; // die on timeout (no data on input) int timeout; // die on timeout (no data on input)
} glob_pars; } glob_pars;

View File

@ -19,12 +19,24 @@
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <usefull_macros.h> #include <usefull_macros.h>
#include "cmdlnopts.h" #include "cmdlnopts.h"
#include "hydreon.h" #include "hydreon.h"
// selected registers threshold over old value
#define VAL_THRESHOLD (5)
// check deviation of values over threshold; return TRUE if |x1-x0|>VAL_THRESHOLD
static int deviat(uint8_t x0, uint8_t x1){
register uint8_t diff = (x0 > x1) ? x0 - x1 : x1 - x0;
if(diff > VAL_THRESHOLD) return TRUE;
return FALSE;
}
static glob_pars *G = NULL; static glob_pars *G = NULL;
static FILE *outf = NULL;
void signals(int sig){ void signals(int sig){
if(sig > 0){ if(sig > 0){
@ -34,6 +46,7 @@ void signals(int sig){
LOGERR("Exit with status %d", sig); LOGERR("Exit with status %d", sig);
if(G && G->pidfile) // remove unnesessary PID file if(G && G->pidfile) // remove unnesessary PID file
unlink(G->pidfile); unlink(G->pidfile);
if(outf) fclose(outf);
hydreon_close(); hydreon_close();
exit(sig); exit(sig);
} }
@ -76,15 +89,76 @@ static void dumpSchanges(slowregs *new, slowregs *old){
} }
} }
static void puttotable(rg11 *R, slowregs *S){
if(!R || !S){ // init -> plot header
fprintf(outf, "%12s%8s%8s%8s%8s" \
"%10s%8s%8s%10s" \
"%8s%10s%8s%8s%10s%8s%8s%8s%8s%8s" \
"\n",
"UNIX time", "PeakRS", "SPeakRS", "RainAD8", "LRA",
"PkOverThr", "Raining", "Freeze", "Out1OnCtr",
"EmLevel", "RecEmStr", "TmprtrC", "ClearTR", "AmbLight", "Bucket", "Barrel", "DwellT", "MonoStb", "LightAD");
return;
}
// old values: we will make dump of selected fields only if |new-old| > threshold
static rg11 oRregs = {0};
static slowregs oSregs = {0};
static size_t Out1ctr = 0;
int changed = FALSE;
// now check selected fields
#define CHKR(r) do{if(deviat(oRregs.r, R->r)) changed = TRUE; oRregs.r = R->r;}while(0)
#define CHKS(r) do{if(deviat(oSregs.r, S->r)) changed = TRUE; oSregs.r = S->r;}while(0)
#define RGMASK (PkOverThr | Raining | Out1On | Freeze)
CHKR(PeakRS);
CHKR(SPeakRS);
CHKR(RainAD8);
CHKR(LRA);
if(!(oRregs.RGBits & Out1On) && (R->RGBits & Out1On)) ++Out1ctr;
if((oRregs.RGBits & RGMASK) != (R->RGBits & RGMASK)){
changed = TRUE;
oRregs.RGBits = R->RGBits;
}
CHKS(EmLevel);
CHKS(RecEmStr);
CHKS(TmprtrF);
CHKS(ClearTR);
CHKS(AmbLight);
CHKS(Bucket);
CHKS(Barrel);
CHKS(DwellT);
CHKS(MonoStb);
CHKS(LightAD);
#undef CHKR
#undef CHKS
#undef RGMASK
if(!changed) return;
fprintf(outf, "%12ld%8u%8u%8u%8u" \
"%10u%8u%8u%10zd" \
"%8u%10u%6.1f%8u%10u%8u%8u%8u%8u%8u" \
"\n",
// "UNIX time", "PeakRS", "SPeakRS", "RainAD8", "LRA",
time(NULL), R->PeakRS, R->SPeakRS, R->RainAD8, R->LRA,
// "PkOverThr", "Raining", "Freeze", "Out1OnCtr",
(R->RGBits & PkOverThr) ? 255:0, (R->RGBits & Raining) ? 255:0, (R->RGBits & Freeze) ? 255:0, Out1ctr,
// "EmLevel", "RecEmStr", "TmprtrC", "ClearTR", "AmbLight", "Bucket", "Barrel", "DwellT", "MonoStb", "LightAD"
S->EmLevel, S->RecEmStr, (S->TmprtrF - 32.)*5./9., S->ClearTR, S->AmbLight, S->Bucket, S->Barrel, S->DwellT, S->MonoStb, S->LightAD
);
fflush(outf);
}
int main(int argc, char **argv){ int main(int argc, char **argv){
initial_setup(); initial_setup();
char *self = strdup(argv[0]); char *self = strdup(argv[0]);
G = parse_args(argc, argv); G = parse_args(argc, argv);
if(G->timeout < 5) ERRX("Timeout should be not less than 5 seconds"); if(G->timeout < 5) ERRX("Timeout should be not less than 5 seconds");
if(!G->logfile) ERRX("Point log file name"); if(!G->logfile && !G->outfile) ERRX("Point at least log or output file name");
check4running(self, G->pidfile); check4running(self, G->pidfile);
if(!hydreon_open(G->device)) return 1; if(!hydreon_open(G->device)) return 1;
if(G->logfile) OPENLOG(G->logfile, LOGLEVEL_ANY, 0); if(G->logfile) OPENLOG(G->logfile, LOGLEVEL_ANY, 0);
if(G->outfile){
outf = fopen(G->outfile, "w");
if(!outf) ERR("Can't open file %s", G->outfile);
}
rg11 Rregs, oRregs = {0}; rg11 Rregs, oRregs = {0};
slowregs Sregs, oSregs = {0}; slowregs Sregs, oSregs = {0};
signal(SIGTERM, signals); // kill (-15) - quit signal(SIGTERM, signals); // kill (-15) - quit
@ -93,16 +167,21 @@ int main(int argc, char **argv){
signal(SIGQUIT, signals); // ctrl+\ - quit signal(SIGQUIT, signals); // ctrl+\ - quit
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
double t0 = dtime(); double t0 = dtime();
puttotable(NULL, NULL);
while(dtime() - t0 < (double)G->timeout){ // dump only changes while(dtime() - t0 < (double)G->timeout){ // dump only changes
if(!hydreon_getpacket(&Rregs, &Sregs)) continue; if(!hydreon_getpacket(&Rregs, &Sregs)) continue;
int changes = FALSE;
if(memcmp(&Rregs, &oRregs, RREGNUM + 1)){ // Rregs changed -> log changes if(memcmp(&Rregs, &oRregs, RREGNUM + 1)){ // Rregs changed -> log changes
dumpRchanges(&Rregs, &oRregs); dumpRchanges(&Rregs, &oRregs);
memcpy(&oRregs, &Rregs, sizeof(rg11)); memcpy(&oRregs, &Rregs, sizeof(rg11));
changes = TRUE;
} }
if(memcmp(&Sregs, &oSregs, sizeof(slowregs))){ // Sregs changed -> log if(memcmp(&Sregs, &oSregs, sizeof(slowregs))){ // Sregs changed -> log
dumpSchanges(&Sregs, &oSregs); dumpSchanges(&Sregs, &oSregs);
memcpy(&oSregs, &Sregs, sizeof(slowregs)); memcpy(&oSregs, &Sregs, sizeof(slowregs));
changes = TRUE;
} }
if(changes) puttotable(&Rregs, &Sregs);
t0 = dtime(); t0 = dtime();
} }
signals(-1); // never reached signals(-1); // never reached

View File

@ -26,15 +26,15 @@
#define SREGNUM 16 #define SREGNUM 16
// RGBits values: // RGBits values:
// raining too much (???) // PeakRS overflow (>255)
#define PkOverThr (1<<0) #define PkOverThr (1<<0)
// is raining (???) // is raining (after several PKOverThr by fixed time)
#define Raining (1<<1) #define Raining (1<<1)
// outern relay is on (???) // outern relay is on (after bucket overflows from 18 to 0)
#define Out1On (1<<2) #define Out1On (1<<2)
// heater (???) // heater is on
#define HtrOn (1<<3) #define HtrOn (1<<3)
// ambient light @0 -> night // ambient light @0 (murky, twilight)
#define IsDark (1<<4) #define IsDark (1<<4)
// ??? // ???
#define Cndnstn (1<<5) #define Cndnstn (1<<5)
@ -50,11 +50,11 @@
#define BUFLEN (32) #define BUFLEN (32)
typedef struct{ typedef struct{
uint8_t PeakRS; // water intensity (255 - continuous) 0..5 uint8_t PeakRS; // water intensity (255 - continuous)
uint8_t SPeakRS; // 0..5 uint8_t SPeakRS; // most time == PeakRS
uint8_t RainAD8; // power of rain (???) 64..192 uint8_t RainAD8; // (???)
uint8_t LRA; // counter of rain activity (???) uint8_t LRA; // average rain activity (~envelope of PeakRS)
uint8_t TransRat; // amount of measurements per second (???) 60..170 uint8_t TransRat; // amount of measurements per second (???)
uint8_t AmbLNoise; // ambient noise RMS (???) uint8_t AmbLNoise; // ambient noise RMS (???)
uint8_t RGBits; // flags uint8_t RGBits; // flags
uint8_t SlowRegIngex; // slow register index uint8_t SlowRegIngex; // slow register index
@ -62,22 +62,22 @@ typedef struct{
} rg11; } rg11;
typedef struct{ typedef struct{
uint8_t RevLevel; // 12 uint8_t RevLevel; // (??? == 14)
uint8_t EmLevel; // 30..80 uint8_t EmLevel; // (???) seems correlated with RainAD8
uint8_t RecEmStr; // 60..66 uint8_t RecEmStr; // (???) seems correlated with RainAD8
uint8_t ABLevel; // 10 uint8_t ABLevel; // (??? == 7..12)
uint8_t TmprtrF; // 70..100 uint8_t TmprtrF; // (inner T)
uint8_t PUGain; // 34..39 uint8_t PUGain; // (??? == 37)
uint8_t ClearTR; // 60..170 uint8_t ClearTR; // (??? almost constant == 121..149)
uint8_t AmbLight; uint8_t AmbLight; // ambient light
uint8_t Bucket; uint8_t Bucket; // Intergal PeakRS. When no rain, decreased near 4 hours per 1 unit
uint8_t Barrel; uint8_t Barrel; // Integral Bucket (increases when Bucket goes througt 12->14 after last overflow). Decreased near 2 hours per 1 unit
uint8_t RGConfig; uint8_t RGConfig; // (??? == 0)
uint8_t DwellT; uint8_t DwellT; // 100 - no rain, 50 - low, 5 - max rain (like exponental function)
uint8_t SinceRn; uint8_t SinceRn; // (0..20) increases every minute after rain is over
uint8_t MonoStb; uint8_t MonoStb; // when Raining==1, MonoStb=15, then decrements when no rain (1 unit per ~1minute)
uint8_t LightAD; // 120..136 uint8_t LightAD; // (???) seems correlated with RainAD8
uint8_t RainThr; uint8_t RainThr; // (??? == 12)
} slowregs; } slowregs;
int hydreon_open(const char *devname); int hydreon_open(const char *devname);

File diff suppressed because it is too large Load Diff