EmbDev.net

Forum: µC & Digital Electronics OpenHR20: Firmware for Honeywell Rondostat HR20E


von Richard G. (gggggg)


Rate this post
useful
not useful
ad2) OK?
#if DEBUG_PRINT_I_SUM
  print_s_p(PSTR(" Is: "));
  print_hexXXXX(sumError);
  print_s_p(PSTR(" Ic: ")); //jr
  print_decXXXX(CTL_interatorCredit);
#endif

3. How can I set Is after reboot manually to a certain value (necessary 
during testing). Do we have a COM command or any other way ... ? Can we 
use the EEprom edit mechanisem some how ??

von Jiri D. (jdobry)


Rate this post
useful
not useful
Richard,
I almost accept your notices. Only one difference is hex output for 
CTL_interatorCredit, reason is missing support for decimal numbers<0.

Jiri

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri did you accept 1 & 2 ???!!!
(I thought credit is only poistive ...)

How can I achieve 3 ??

4. How come - see sumerror
D: d6 19.03.11 09:41:08 M V: 56 I: 2317 S: 2300 B: 2707 Is: e1f0
D: d6 19.03.11 09:45:08 M V: 56 I: 2317 S: 2300 B: 2706 Is: e168
D: d6 19.03.11 09:49:08 M V: 56 I: 2317 S: 2300 B: 2705 Is: e0e0
1
D: d6 19.03.11 09:53:08 M V: 55 I: 2324 S: 2300 B: 2702 Is: e020
2
D: d6 19.03.11 09:57:08 M V: 55 I: 2324 S: 2300 B: 2701 Is: df60
3
D: d6 19.03.11 10:01:08 M V: 59 I: 2324 S: 2300 B: 2694 Is: ff40
D: d6 19.03.11 10:05:08 M V: 59 I: 2330 S: 2300 B: 2701 Is: fe50
D: d6 19.03.11 10:09:08 M V: 59 I: 2330 S: 2300 B: 2701 Is: fd60
around 10:05 valve started calibration ??? why ? today is saturday

von Richard G. (gggggg)


Rate this post
useful
not useful
THX: just verified the changes ;-)
bat voltage display has a prob = shows only 2. instead of 2.123
        LCD_Print
1
Char
(bat_average/1000, 2, LCD_MODE_ON);

        LCD_PrintDec(bat_average/100, 2, LCD_MODE_ON);
        LCD_PrintDec(bat_average%100, 0, LCD_MODE_ON);

Jiri please stay with /100, because this way I see wether accu is 
charging or discharging earlier (I charge them from PLC) THX

pls comment on 3 & 4

von Richard G. (gggggg)


Rate this post
useful
not useful
Regarding alternate and service watch from one of the last posts should 
no be left automatically (because we want to watch a certain parameter 
for a longer time ;-) menu.c 125:
1
        } else if (( kb_events & KB_EVENT_NONE_LONG ) && 
2
           ! (menu_state>=menu_home2 || menu_state<=menu_home5 || menu_state==menu_service_watch)) {

von Chris (Guest)


Rate this post
useful
not useful
@Richard: I have to wait until I get my jtag programmer back.... don't 
know how long it will take....

BTW: The rondostat at which I caused the short circuit keeps running 
into E3 error.
Question: When is battery voltage meassured? For me it looks as if it is 
read only at startup, because that coult perhaps explain the wrong 
voltage (?)

von Chris (Guest)


Rate this post
useful
not useful
@Jiri: There is no other power source:

- At the other rondostats which are mounted at the radiators, there is 
an external circuit connected which captures the serial data and sends 
values using rfm12. It gets its power from the rondostat. So it will 
perhaps add capacity, but it definitly is no power source ;)

- The logic analyzer is connected to gnd and tx pin, but it has high 
impedance inputs, no pullups and so on.

von Richard G. (gggggg)


Rate this post
useful
not useful
battery is measured quite often (<10s)...wait until you have your 
programmer back. there is a bat display in alternate menue already ;-)

von Jiri D. (jdobry)


Rate this post
useful
not useful
batt voltage show only 2. ? For me it is correct, show 2.55.

You don't need 3) it is almost equal to config.valve_center. Difference 
is only in units. Problem is that we don't have free flash for any 
useful idea.

Every Sat on 10:00 is automatic recalibration. It is useful also for 
keep valve heath.

von Jiri D. (jdobry)


Rate this post
useful
not useful
I change battery voltage in LCD back to mV without decimal point.

battery voltage is measured every second. Presented value is average 
from last AVERAGE_LEN (= default 15) values

von Richard G. (gggggg)


Rate this post
useful
not useful
men you are fast THX "mV"

Regarding alternate and service watch from one of the last posts should
no be left automatically (because we want to watch a certain parameter
for a longer time ;-) menu.c 125:        } else if (( kb_events & 
KB_EVENT_NONE_LONG ) &&
           ! (menu_state>=menu_home2 || menu_state<=menu_home5 || 
menu_state==menu_service_watch)) {

ad3) in my case different heaters have quite different valves, so for 
testing purposes it would be great to start with manual set Is by COM or 
LCD. I thought during debuggin it would be quite helpfull to be able to 
manipulate static variables or variables from service_watch

von Jiri D. (jdobry)


Rate this post
useful
not useful
Richard,

add to your sumErr log (4): I down know why, it looks strange.

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
here it is. around 7pm, 9pm, and today 5am and 7:40 there is a temp 
update with same temp=23.0

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
Jiri Bat display does not work for me with CHAR. I press middle button 
right after version string and DATE skip define is set ! Display shows 
10:00 (no clear screen) and when first bat calc is done the left 0 looks 
like this
-
-

von Richard G. (gggggg)


Rate this post
useful
not useful
1
                    if (((CTL_error &  (CTL_ERR_BATT_LOW | CTL_ERR_BATT_WARNING)) == 0)
2
                  && (RTC_GetDayOfWeek()==6)
3
                && (RTC_GetHour()==10)
4
                && (RTC_GetMinute()==0)) {
5
                        // every sunday 10:00AM
6
                        // TODO: improve this code!
7
                        // valve protection / CyCL
6 .. then is saturday and not sunday as stated in comment ???

von Chris (Guest)


Rate this post
useful
not useful
I connected a rondostat to a variable power source. When it callibrates 
and I change power, the motor of the rondostat gets slower or faster, 
but it returns to its normal speed after a very short time (a second or 
so).
So the voltage messurment seems to work.

Strange1:
I set it to 3.0V, but it displays "batt". Why? Is this condition cleard 
automatically when voltage rises, or only at reset or button-event?

Strange2:
Serial Output reports a voltage of 3,06V now.
Multimeter says 3,06V too (hm, very precise, it was rather cheap....)
Power-Supply is set to 3,0V.
=> All correct.
But when it was on batteries, the same rondostat showed 3,2V (serial) 
while real voltage was 2,8V.

I set power supply to 2,8V now. Serial reports 2,87V now.
I set power supplay to 3,5V, serial reports 3,5V.

Connected batterys while power supply is still connected to prevent 
reset, then disconnected power supply. Serial shows 2,8V, real voltage 
is 2,8V. Still shows batt.

Removed and reinserted batteries to do a reset. Real voltage is still 
2,8V
. Batt-Message is gone, serial output reports 3,55 or more volts. Motor 
speed seems to be lower and when it starts the boost is barely there.

Switched on power supply (3V), batteries still in the rondostate. Serial 
still shows 3,55V or greater.

von Richard G. (gggggg)


Rate this post
useful
not useful
bat displays are not reversible (except reboot or #define). Once voltage 
droped below 2,4 bat warning comes on. Low bat is 2.0.
On my defect valve I also could not reproduce the situation ... I gues 
if you try it several times (powerless in between each time!!) with 
powersupply you will get wrong readings there as well

von Jiri D. (jdobry)


Rate this post
useful
not useful
- battery warning and error is not reversible by good reason. Battery on 
end of life usually refresh voltage without stress. In this situation is 
show low voltage information only when motor runs.  I want to keep this 
information.

- I fix "char" problem on voltage on LCD.

Richard: You are right about mistake in comment about Saturday automatic 
recalibrate.

Chris: I don't have any idea why batteries is measured wrong and 
external power supply is OK. I am not able repeat this problem. Maybe 
some difference on PCB? Just idea, can you compare your PCB with photos 
and other documentation?

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri: 339 bat display OK, but we have a : in display (before we had a .)

a) Do we realy need the Highword of summerror .. it is FFFF or 0 and if 
it is ffff the lowword will start with f..a anyway ?? But it is cleaner 
code of course ;-)

b) It would be quite usefull, if one could choose, that
alternate menue (middle button) and watch menue do not return
automatically to main menue. This way one could watch a specific
parameter without warming up the valve (by pressing the buttons all the
time) ... and it would be a lot easier during testing our valve setup 
...
I hope to convice you ;-) menu.c 125:
1
        } else if (( kb_events & KB_EVENT_NONE_LONG ) && 
2
           ! (menu_state>=menu_home2 || menu_state<=menu_home5 || menu_state==menu_service_watch)) {
c) did you find anything in my log ?

von Jiri D. (jdobry)


Rate this post
useful
not useful
":" in voltage fixed

a) it could be 0x00012345 or 0xffff2345. Low word is same, but meaning 
is different

b) I want to have automatic return to main_menu. You can create change 
on your sources and it will kept after "svn update" command.

c) what is wrong on this log? PS: create chart in OpenOffice or Excel is 
sometimes useful.

von Richard G. (gggggg)


Rate this post
useful
not useful
a) What was your maxsumerror so far ? mine typ. stops at ffff a/9

b) I tried snv commands some time ago, but it doesnt work in some of my 
network surroundings (proxy,firewall,...), so I have to patch al my 
changes all the time

hope to convince you at least to:
1
        } else if (( kb_events & KB_EVENT_NONE_LONG ) 
2
#if NO_AUTORETURN_FROM_ALT_MENUES 
3
           && ! (menu_state>=menu_home2 || menu_state<=menu_home5 || menu_state==menu_service_watch)) 
4
#endif  {

c) I dont understand, thought you mentioned something strange  ...

von Jiri D. (jdobry)


Rate this post
useful
not useful
strange is this part:
D: d6 19.03.11 09:57:08 M V: 55 I: 2324 S: 2300 B: 2701 Is: df60
D: d6 19.03.11 10:01:08 M V: 59 I: 2324 S: 2300 B: 2694 Is: ff40

what happen at this time?

von Richard G. (gggggg)


Rate this post
useful
not useful
I thought sat 10:00 auto_calibration, main.c 241
                    if (((CTL_error &  (CTL_ERR_BATT_LOW | 
CTL_ERR_BATT_WARNING)) == 0)
                  && (RTC_GetDayOfWeek()==6)
                && (RTC_GetHour()==10)
                && (RTC_GetMinute()==0)) {
                        // every saturday 10:00AM
                        // TODO: improve this code!
                        // valve protection / CyCL
1
                       sumError=0;
sumerror=0 should not happen here ! right ? should only happen if valve 
is taken from head (E2)

von Jiri D. (jdobry)


Rate this post
useful
not useful
Richard: right, I must fix it

von Richard G. (gggggg)


Rate this post
useful
not useful
1a ... I hope I may be looking forward to my bonus ;-)
"#if NO_AUTORETURN_FROM_ALT_MENUES"

von Richard G. (gggggg)


Rate this post
useful
not useful
R341: Jiri, why should autocalib need new sumerror. 99 times out of 100 
;-) calib stays about the same ! This way every saturday it gets to hot 
or to cold at 10:00. I think giving credit is good enough !!
Only if valve is taken from head (E2) we should reset sumerror ...

von Jiri D. (jdobry)


Rate this post
useful
not useful
max sumError if defined on controller.c line +-319 (max inpact to valve 
is 50%)

option NO_AUTORETURN_FROM_ALT_MENUES is added

von Jiri D. (jdobry)


Rate this post
useful
not useful
Richard,

Calibration is same only on same conditions. But normally last 
calibration is 1 week old. And it depend to battery, heater tempterature 
atc.
But you are right, last value can be better than 0. I will create option 
for it.

von Richard G. (gggggg)


Rate this post
useful
not useful
THX and a beer for R342:

Yes regarding impact of max 50%, but you agree that most times autocalib 
will bring about the same results ... so we do not need sumerror=0 here 
!! giving credit to adapt little changes will be good enough. (in my 
case 5% change mean 1-2°C more/less in the room. min/max/center are 
quite different on my heaters; they also have different valvetypes)

Only if valve is taken from heater (E2) we should start all over again 
with sumerror=0

von Richard G. (gggggg)


Rate this post
useful
not useful
R343: Why not ?
#if CyCL_RESETS_sumError
sumError=0; // new calibration need found new sumError
CTL_interatorCredit=config.I_max_credit;
integratorBlock= DEFINE_INTEGRATOR_BLOCK (or eeprom)
#else
CTL_interatorCredit=config.I_max_credit;
integratorBlock= DEFINE_INTEGRATOR_BLOCK (or eeprom)
#endif

When do we need the block ? Also here ?:
    if (mont_contact & KBI_MONT) {
        CTL_error |=  CTL_ERR_MONTAGE;
    sumError=0;

von Richard G. (gggggg)


Rate this post
useful
not useful
suggestion:
#if CyCL_RESETS_sumError
  sumError=0; // new calibration need found new sumError
#endif
  CTL_interatorCredit=config.I_max_credit;

______controller.c
   if (CTL_interatorCredit==config.I_max_credit) {
      integratorBlock=DEFINE_INTEGRATOR_BLOCK (or eeprom)

   if (updateNow) {

von Jiri D. (jdobry)


Rate this post
useful
not useful
Try R327

von Richard G. (gggggg)


Rate this post
useful
not useful
you mean 344 ;-) ... tommorow ... my girls are waiting ... see you

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, I verified all the changes compared to 339:
!!! VERY VERY  WELL DONE !!!

Suggestion regarding controller:
1.Your new idea from last weeks regarding I part works well. But 
sometimes an offset 0,1-0,2 stays. I know that is not much ;-). My 
suggestion is to give credit, if error is around 0 (instead=0). Existing 
code
     if (absErr >= last2AbsError) { // error can grow only limited time
will prevent growth of sumerror anyway.
An Option could be to give the "tollerance credit" just once. But this 
would produce more code ;-). This is why we should try this first:
1
      if ((error16 >= 0) ? (v0 < config.valve_max) : (v0 > config.valve_min)) {
2
        if (((lastErrorSign != ((uint8_t)(error16>>8)&0x80))) || 
3
            ((absErr==last2AbsError) && (absErr<=I_0_TOLLERANCE))) { //sign of last error16 != sign of current OR abserror around 0
4
          CTL_interatorCredit=config.I_max_credit; // give credit

#define I_ERR_TOLLERANCE_AROUND_0 15 // unit 0,01°C. Set it quite 
restrictive !


2. I suggest a define in controll.c 303:
            CTL_interatorCredit-=(absErr/I_ERR_WEIGHT)+1; // max is 
1200/25+1 = 49 impact of error on I part

#define I_ERR_WEIGHT 25 //impact of error on I part

von Chris (Guest)


Attached files:

Rate this post
useful
not useful
Hi Jiri,

I logged temperature and vent position in one room to see the 
overheating in the morning. Here it is.

Any idea what causes the wrong battery messurements? Why is is it after 
reset and not before with the same rondostat? Strange.

Chris

von Chris (Guest)


Rate this post
useful
not useful
btw: The "own sensor ic2" does not messure room temperature. You can 
ignore it.

von Chris (Guest)


Rate this post
useful
not useful
Hi,

I got my jtag programmer back and flashed rev 344 (without rfm12).

I hear the initial boost of the motor (I see you disabled compensation 
in config.h, so wrong battery messurements should not be a problem any 
more?)

Bat on lcd shows 3281, multimeter shows 2,89V.

Csn I use rev 344 as "productive" version, or won't it work?

Chris

von Richard G. (gggggg)


Rate this post
useful
not useful
I also use it with the mods from above - no prob so far

von Chris (Guest)


Rate this post
useful
not useful
I took the batteries in and out several times. There was nothing else 
connected to the rondostat and I did not mount it. Here is the batt 
output:

2,8V (ok)
3,5V
4,4V
5,4V
2,8
2,9
2,9
3,1
2,9
2,9
2,9
2,9
2,9

von Richard G. (gggggg)


Rate this post
useful
not useful
same on my defect one

von Chris (Guest)


Rate this post
useful
not useful
Could it be a bug somewhere in the firmware (ad-init?) or a bug of the 
atmega itself?

I don't think it is a "defect" in hardware because it occurs only 
sometimes and changes only on reset (not sure about this... I never 
watched a rondostat whith wrong messurements correct itself without 
reset... did you?)

I habe 6 rondostats with openhr20 that work like a charm (except for the 
overheating problem in the morning which is in all rooms).

And I have 4 rondostates which are not mounted because auf E3 problem / 
wrong voltage problem or wrong callibration byte so serial data is not 
working. (how can I correct this?)

von Richard G. (gggggg)


Rate this post
useful
not useful
I agree but have no idea how to get closer to the reason

von Jiri D. (jdobry)


Rate this post
useful
not useful
Chris, comments to your values:
You have externaly disabled heating and SW wan't to fix this error. 
Mechanism to do it is integrator (old name was "zero error 
compensation")
Problem is that current version of windup protection not help in this 
situation (I will improve it later).
Soloution for you is set I_Factor to 0 and set valve_center very precise 
manualy.

von Jiri D. (jdobry)


Rate this post
useful
not useful
Chris, I have idea how to solve your problem. Please wait till tomorrow.

von Jiri D. (jdobry)


Rate this post
useful
not useful
I thing that problem with regulator windup on "central heating off" can 
be solved on Rev345. It need tests.

I have NO idea where is problem with bad battery measure. But I create 
some debug, please enable DEBUG_BATT_ADC in debug.h and report me 
result. (need SVN rev 346)

von Richard G. (gggggg)


Rate this post
useful
not useful

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, men you are fast - when I was ready with patching 349, you were at 
350 already. I take this for the night ;-)

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri add this to com.c ?!
#if DEBUG_PRINT_I_SUM
  print_s_p(PSTR(" Is: "));
  print_hexXXXX(sumError>>16);
  print_hexXXXX(sumError);
  print_s_p(PSTR(" Ib: ")); //jr
  print_hexXX(CTL_integratorBlock);
  print_s_p(PSTR(" Ic: ")); //jr
  print_hexXX(CTL_interatorCredit);
  print_s_p(PSTR(" Ie: ")); //jr
  print_hexXX(CTL_creditExpiration);
#endif

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri could you please explain the changes regarding controller since 344

von Jiri D. (jdobry)


Rate this post
useful
not useful
It s simple:

- when integrator credit is empty or temperature change I compare 
current error with error on last change. If it isn't smaller than 1/2 
change on integrator is reverted.
- integrator credit have limited lifetime

von Richard G. (gggggg)


Rate this post
useful
not useful
1. OK. Isnt the aim of CTL_interatorCredit and CTL_creditExpiration the 
same. Both expire. The 3rd function is revert (I think its a good idea).
All 3 mechanisems have the same goal = prevent windup = right ?

This is why I dont understand why we need CTL_creditExpiration - pls 
explain?

2. When do I have to change I_ERR_WEIGHT and when I_Factor ?

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
ad2) log from last night: Impact on I at errors <0,5°C is to low / to 
slow ...

von Jiri D. (jdobry)


Rate this post
useful
not useful
too slow? Try create chart in excel. I can't be better. :-)

We need 2 different
CTL_interatorCredit - allow maximum change volume, depend to integrator 
change size
CTL_creditExpiration - allow maximum time

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, I nearly expected your answer ;-) ... I am perfectionist ...
as you know ...

But right now I have the prob, that Summeroor, Ic and Ib in bathroom is 
= 0 (I dont know Ie). Instead of 24 I have 26° = just P part active .. I 
have no log and no idea so far ... maybe the gap is too big, as that it 
is closed during credit/expiretime

2. When do I have to reduce I_ERR_WEIGHT and when increase I_Factor ?

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri:
a. if (absErr>=(lastTempChangeErrorAbs/2)) reverts too often ...

If just by chance the error is quite small we freeze wrong I part value 
"forever". E.g. in some of my rooms (e.g.bathroom) I have a floor 
heating as well. So it is not valve on its own who tries its best, doors 
to other rooms sometimes stay open the whole day,...). In R351 valve 
reverted quite often and ended up beeing controlled by P part close to 
center. Bathrooom has 26 instead of 24 this way. So this "one time small 
error" might be quite wrong, because it was produced by external 
influences !!

Generell revert aim is to prevent wrong summerror produced by external 
influences (shorten the time to correct I part). So aim is, to just 
revert if really necessary ...

Suggetsion: revert if:
(absErr>=lastTempChangeErrorAbs) && (absErr>=I_REVERT_TEMP_THRESHOLD) && 
(lastTempChangeSumError>=I_REVERT_ERR_TRESHOLD)

#define I_REVERT_TEMP_THRESHOLD 50  //unit 0,01°C, revert only if error 
is larger than e.g. 0,5°C. Dont go for small errors that by chance might 
have been produced by external influece and will be stored "forever" !

#define I_REVERT_ERR_THRESHOLD 0x1000 //revert only if sumerror has 
impact on valve move = do not revert on small values that have no impact 
on valve position. This way even wrong sumerrors will be corrected 
during the first periode, where external influence is gone.

b. expiration credit: do we relly need this ?
I understand, that aim is to stop valve during non heating periodes: If 
no temp change occures, I part should be frozen to stop valve from 
moving.
This is why I would like to set it to 24hours (no tempchange a whole 
day) =24x60/4=360 but max is 255 ;-)

c) please answer 2. from last post...

von Richard G. (gggggg)


Rate this post
useful
not useful
a) must be:
.. && .. && (abs(lastTempChangeSumError)>=I_REVERT_ERR_TRESHOLD)

von Jiri D. (jdobry)


Attached files:

Rate this post
useful
not useful
Idea for "revert" is solve 2 situations:

Ex1: you want to heat more, but central heating is switched off. 
Integrator will move valve. And we need detect this situation: we are 
not able to heat up, valve position have no effect

Ex2: you need lower temperature, but temperature declines too slowly 
(open door, external heat source) Situation is same, any change on valve 
can't help. See too attachment

I both situation: any integrated change of valve is invalid, because it 
can't have any effect
------------------------
expiration - Lets this situation:
22degrre in room, wanted temperature is 18. It take many hours to pass 
20degrre and it leave valve_min position. Now valve slowly grow and 
follow temperature decline. Without expiration, integrator will decline 
valve without reason again to valve_min.

expiration in other words: If valve change have not effect in defined 
time (default 2 hours!!!) we can't believe that measured error depend to 
valve position. We must have impact from another source. Maximum 
expiration is (255*4/60) = 17 hours Do you believe that measured effect 
after 17 hours is caused by valve change?

------------------------

But you are right, condition (absErr>=(lastTempChangeErrorAbs/2)) can be 
too strong. I will change it.

(absErr>=I_REVERT_TEMP_THRESHOLD) <= bad idea, compare it mainly with 
Ex2, it will not work in this situation

(abs(lastTempChangeSumError)>=I_REVERT_ERR_TRESHOLD) <= tell me why? 
What is a goal?

------------------------

"When do I have to reduce I_ERR_WEIGHT and when increase I_Factor?"
A: Anytime, and see whats happen. Frankly spoken, I don't know ideal 
setting for this. It is too new, I have only limited data (only my 
valves, only short time).

------------------------
Ideal solution for enable/disable integrator update is put all magic 
like "credit" to trash and use "regression analysis" to determine rate 
of valve change to temperature. It is perfect clear solution. But we 
have limited resources in MCU. If you enable all options on code, free 
space in flash is less than 0.5kB (less than 250 assembler 
instructions!!) This is reason why I disable program/time settings by 
valve wheel on wireless case. Now I have 1432bytes free flash. It make 
it possible.
I will try create better mathematical model of valve (not just 
calc/excel sheet) and try press some "regression analysis" into code.
But I am sure that end of heating season will be faster.

von Richard G. (gggggg)


Rate this post
useful
not useful
also today bathroom was reverted the whole day ....

idea a) and b) work togehter !

ad (abs(lastTempChangeSumError)>=I_REVERT_ERR_TRESHOLD) <= tell me why?

This way we just do a revert if the sumerror which we take for revert 
has an impact on valve (the effect should be >= 1% ...)

e.g. we have stored a lastTempChangeSumError=0x050 at a 
lastTempChangeErrorAbs=0,1°C. But those values were influenced by 
externel source.
R351 will revert all the time 0x050 because abserr will be > 
lastTempChangeErrorAbs=0,1°C most time. And when the ext. source is gone 
abserror will get larger all the time ... As I is small 0x050 it has no 
impact ... and I part is OFF "forever".

(abs(lastTempChangeSumError)>=I_REVERT_ERR_TRESHOLD) secures that we 
just revert sumerrors that have a real influence (e.g. >=1%) on valve.

And if this lastTempChangeSumError was wrong (because of ext. influence) 
it will lead to a larger error, which will not be reverted again because 
of my condition a) !!!!!!!

I think A&B together will work for both examples, because we revert on 
large errors.

von Richard G. (gggggg)


Rate this post
useful
not useful
my explanation was not quite OK.
b) on its own secures: Only revert values (e.g >0x1000) that have real 
impact. So if stored values were wrong, the error will get worse and I 
part will start working

a) if stored values were wrong, one of the next periodes for sure will 
be able to reduce the error below 0,5°C(I_REVERT_TEMP_THRESHOLD) ... and 
reverting will stop

I gave a&b a try for tommorow in bathroom

von Richard G. (gggggg)


Rate this post
useful
not useful
ad b) when I say "I part eill start working" I mean this part !
          if (absErr >= last2AbsError) { 
CTL_interatorCredit-=(absErr/I_ERR_WEIGHT)+1; // max is 1200/20+1 = 61

von Jiri D. (jdobry)


Rate this post
useful
not useful
Richard
but you compare integrated value, not change from last temperature 
change. It can't work.
Or I understood wrong. Any chart ?

von Richard G. (gggggg)


Rate this post
useful
not useful
no chart ... log will come tommorow ....

goal of a)
Do not revert on small errors, this way valve can get out of REVERTING 
by itself (it gets out of the trap if controller controls the error to < 
0,5°)
If we dont limit the error REVERTING will last "forever" (e.g. if 
lastTempChangeErrorAbs=0), because controller cant do any better. But if 
the sumerror stored is wrong controller is in the trap!!)

b) only revert if I part has influence on controller. small summerrors 
have no effect on valve position. Only P part works. Large values have 
real influece on position. So if wrong (large) summerror will be 
reverted, position will be worse then before (when the ext. source was 
active). This way I part "if (absErr >= last2AbsError)" will start 
working on this error and next time abserror will be <0,5 and reverting 
will stop....

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
(absErr>=lastTempChangeErrorAbs) && (absErr>=I_REVERT_TEMP_THRESHOLD) &&
(abs(lastTempChangeSumError)>=I_REVERT_ERR_TRESHOLD)

1. V starts with 43 (center= 58, Min=42) through P part
23.03.11 23:41:42 Ic is used up but V is 44 now:
So I_Factor should be increased to at least compensate the loss on P. We 
should have V<42 there.

Jiri we should increase I to 35

2. 24.03.11 04:03:03 Tempchange to 2300:
summerror stays as Vmin is reached. room is heated up by floor heating, 
...

no revert was necessary > no revert done > OK

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
another room: Vmin=52 Center=58 I set Vmin at 18:02:03 and Ifactor to 35 
around 17:38

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
bathroom during last night: Vmin=40, Center=58, I=35
heater stops heating about V=41
At the beginning valve was warmed up from my hands... I think I is still 
to low ?!

von Jiri D. (jdobry)


Rate this post
useful
not useful
Richard, why do you set Vmin too close? This result is not surprise, 
controller disable integration if valve is out of range and in your case 
it usual situation. Except this, valve calibration depends to battery 
status, and with this setting is easy to see valve on Vmin and heating 
warming.

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, I thought battery should not interfear, beacause we count pulses 
... ?
Actually I set Vmin = VheaterOFF - 4. This way I part cant "wind down". 
-4 was good enough so far to compensate the calibration tollerances 
which usally are not more than 2.
If you read the bathroom logs, be aware that bathromm has floor heating, 
hand towel hater (with normal valve, shuts down about 26°C) and the 
heater controlled by hr20. And if door is opened temp slowly goes down 
to 24. This room is perfect for testing the reverting prob I had with 
R351 ;-).

von Jiri D. (jdobry)


Rate this post
useful
not useful
Valve calibration depend to battery because maximum force depend too.
It is simple, motor controller try to keep same speed till slow down on 
"close end" (Ad3 state). Problem is that maximum force depend to battery 
state (maximum PWM is constant). I my valves valve range is ~600pulses 
end to end with fresh batteries and ~480pulses with end of live 
batteries.
(if you need exact position of valve, try to find "manual calibration" 
in this thread)

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri,
- #define WATCH_N (10) should be (11) (values 0..0a)

- why dont we start autocalibration with searching CLOSE first. This way 
one could manually set head to CLOSE, mount valve, valve checks that it 
cant go any further and store this manually set CLOSE, then valve goes 
to OPEN. This way we could reproduce the CLOSE position in automatic as 
well .. ?

von Richard G. (gggggg)


Rate this post
useful
not useful
- why dont we store the positions found during automatic calib in eeprom 
?

von Richard G. (gggggg)


Rate this post
useful
not useful
- e.g. by setting MOTOR_ManuCalibration |= 0x8000
0 ... no calib, >0 ... auto, <0 ... manu

von Jiri D. (jdobry)


Rate this post
useful
not useful
WATCH_N you are right, fixed

Calibration starts to "OPEN" direction by few reasons:
- when valve is on "CLOSE" side, force to start closing depend to valve 
position. I will create calibration depend to position on start 
salibration.
- when valve is "CLOSE" side, it can be on position, where motor have 
not force to reach. In another word, manually you can brace stronger 
than motor.

Where is benefit if you store automatic calibration in EEPROM? If you 
remove had from valve you must calibrate it anyway.

von Richard G. (gggggg)


Rate this post
useful
not useful
THX for explanation regarding calib start direction

Benefit - what I am looking for:
a) one would like to see, wether position ater valve install is about 
the same like last time. So we can be sure everything is fine.

b) right now I always look at MOTOR_PosMax to see wether the number of 
pulses are about the same (the gap so far always was < 10 pulses, this 
is about 2% from 0x200 to 0x2d0 pulses on my valves.

c) one thing could be to set calibration data manually

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
Jiri,
1 I think we should give integrator credit when valve starts moving 
because of p part e.g.:
D: d7 27.03.11 00:13:57 M V: 41 I: 2520 S: 2450 B: 2491 Is: ffffc900 Ib: 
00 Ic: fd Ie: e2
D: d7 27.03.11 00:17:57 M V: 41 I: 2520 S: 2450 B: 2489 Is: ffffc900 Ib: 
00 Ic: fd Ie: e1
D: d7 27.03.11 00:21:57 M V: 41 I: 2520 S: 2450 B: 2488 Is: ffffc900 Ib: 
00 Ic: fd Ie: e0
D: d7 27.03.11 00:25:57 M V: 42 I: 2516 S: 2450 B: 2490 Is: ffffc900 Ib: 
00 Ic: fd Ie: df
D: d7 27.03.11 00:29:57 M V: 42 I: 2514 S: 2450 B: 2490 Is: ffffc900 Ib: 
00 Ic: fd Ie: de
D: d7 27.03.11 00:33:57 M V: 42 I: 2514 S: 2450 B: 2492 Is: ffffc900 Ib: 
00 Ic: fd Ie: dd
D: d7 27.03.11 00:37:57 M V: 42 I: 2514 S: 2450 B: 2488 Is: ffffc900 Ib: 
00 Ic: fd Ie: dc

controller.c 399:
1
  if ((lastCTL_interatorCredit<=0) && (pi_term16!=(uint8_t)processValue)) {  //give credit if p part moves valve
2
                CTL_interatorCredit=config.I_max_credit; 
3
                CTL_creditExpiration=config.I_credit_expiration;
4
  }            
5
  return (uint8_t)pi_term16;
    last2AbsError = lastAbsError;
    lastAbsError = absErr;
    lastErrorSign = (uint8_t)(error16>>8)&0x80;
1
    lastCTL_interatorCredit = CTL_interatorCredit;

2. REVERT http://embdev.net/topic/118781?goto=2120075#2116213
(absErr>=lastTempChangeErrorAbs) && (absErr>=I_REVERT_TEMP_THRESHOLD) &&
(abs(lastTempChangeSumError)>=I_REVERT_ERR_TRESHOLD)

works OK. see log D: d6 26.03.11 21:34:12

von Richard G. (gggggg)


Rate this post
useful
not useful
ad1) integrator_block was missing:
1
  if ((lastCTL_interatorCredit<=0) && (pi_term16!=(uint8_t)processValue)) {  //give credit if p part moves valve
2
                CTL_interatorCredit=config.I_max_credit; 
3
                CTL_creditExpiration=config.I_credit_expiration;
4
                CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK;       //block to wait for p part impact
5
  }            
6
  return (uint8_t)pi_term16;

von Richard G. (gggggg)


Rate this post
useful
not useful
ad1)
1
   if ((lastCTL_interatorCredit<=0) && ((uint8_t)pi_term16!=(uint8_t)processValue)) {  //give credit if p part moves valve
2
                CTL_interatorCredit=config.I_max_credit; 
3
                CTL_creditExpiration=config.I_credit_expiration;
4
                CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK;       //block to wait for p part impact
5
  }            
6
  lastCTL_interatorCredit = CTL_interatorCredit;
7
  return (uint8_t)pi_term16;

von Richard G. (gggggg)


Rate this post
useful
not useful
I think its even better to block integrator after any change of valve 
position caused by p part
1
  if ((lastCTL_interatorCredit==CTL_interatorCredit) && (uint8_t)pi_term16!=(uint8_t)processValue) {  
2
    CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK;       //block Integrator if only p moves valve
3
    if (lastCTL_interatorCredit<=0) {  // if credit is expired
4
      CTL_interatorCredit = config.I_max_credit; //give new credit if p part moves valve
5
      CTL_creditExpiration = config.I_credit_expiration;
6
    }
7
  }            
8
  lastCTL_interatorCredit = CTL_interatorCredit;
9
  return (uint8_t)pi_term16;
a better position to implement blocking after P change could be line 
175, but then we need something like lastSumError ...

von Richard G. (gggggg)


Rate this post
useful
not useful
I took wrong variable: instead of process_value we have to use 
old_result of course ...
1
   if ((lastCTL_interatorCredit==CTL_interatorCredit) && (uint8_t)pi_term16!=old_result) {  
2
    CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK;       //block Integrator if only p moves valve
3
    if (lastCTL_interatorCredit<=0) {  // if credit is expired
4
      CTL_interatorCredit = config.I_max_credit; //give new credit if p part moves valve
5
      CTL_creditExpiration = config.I_credit_expiration;
6
    }
7
  }            
8
  lastCTL_interatorCredit = CTL_interatorCredit;
9
  return (uint8_t)pi_term16;

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
controller.c 312 uint8_t v0 = valveHistory[0];
why dont we use old_result here ?

my changes did well over the night ...also revert ... see LAST PART of 
log: Vmin=36
PS: I set blocking to 3 to get faster results during testing phase. 
credit_expiration=FF

PPS: Maybe we could give credit on each P Move instead of just if credit 
is expired ...

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
log from normal room (16m²) Vmin=52/54

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, did you or others ever think about or try replacing the thick 
wires of the temp sensor by very thin ones to get faster temp respons 
???

BTW: I am blocking integrator now after any move of valve

von Richard G. (gggggg)


Rate this post
useful
not useful
did someone ever try to move in smaller steps - is it possible to count 
and stop 0,5% ?

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
hu hu ... any anwsers to my last posts would be very welcome ...

the attached jpg shows R354, reverting deactivated and integrator 
blocked after any move of valve... as one could see in small rooms 
(16m²) with outside temps >10°C our actual 1% valve step is too big for 
me...

Heating was deactivatetd in the afternoon, because of sun ..

blocking I: controller.c 396
1
  
2
  } 
3
  if ((uint8_t)pi_term16!=old_result) {  
4
    CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK;       //block Integrator on any valve move
5
  }            
6
  return (uint8_t)pi_term16;

von Richard G. (gggggg)


Rate this post
useful
not useful
1. did you or others ever think about or try replacing the thick
wires of the temp sensor by very thin ones to get faster temp response
???

2. did someone ever try to move valve in smaller steps - is it possible 
to count
and stop 0,5% ?
2a what do I have to change  to try it ?

3. in the morning I want to boost temp 1-2° as fast as possible. The 
actual controller is way to slow to get the childs room warm in the 
morning. We need something like:
if the new wanted temp differs by more than e.g. 1°C from the actual 
setpoint we have to open/or close the valve with another algorithm and 
hand over to the actual controller one some time or if temp is within 
0,3°C to the new temp wanted ...

von Jiri D. (jdobry)


Rate this post
useful
not useful
1. Why? You don't need faster response. Frankly spoken, compare to 
heating response it is fast enough.

2. motor.c function MOTOR_Goto replace 100->200. But you need check all 
valve calculation, because after this same values can be overloaded. You 
must also update LCD and COM functions for correct reports.

3. It if exactly reason for P3_Factor. It is "boost" for big temperature 
difference.

von Jiri D. (jdobry)


Rate this post
useful
not useful
Richard G, about "blocking I: controller.c 396":
It is interesting idea, I will test it too.

von Richard G. (gggggg)



Rate this post
useful
not useful
1. As heater heats up valve. the temp sensor is heated up via its wires. 
With thin wires, see chart 06:30 
hr20_1354_110401a_thin_wire_blocking_I.jpg the impact on sensor is less. 
Sensor is still heated up, but just by air. This way we are closer to 
real room temp. Newer valves from other manufacturers have smd sensors 
with 0,2mm lines...

3. I implemented a boost function...quite preliminary still... just 
using max and min positions of valve. This is the fastest way to heat up 
or cool down... in the next step I will calculate boost_time depending 
on error.. see chart 6:10 hr20_2354_110402a_thin_wire_boost.jpg

Description:
if setpoint is changed and gap is larger than setpoint_diff (50=0,5°) 
and actual error is large enough (boost_error 30=0,3°) we start boost 
funtion. boost sets valve to max or min position depending on error. 
boost lasts for boost_time in minutes (15). boost ends earlier if actual 
error is less than boost_error - boost_hystereses (30-10=0,2°). During 
boost PID controller only calculates errors (no PID values) and 
integrator is blocked.

eeprom.h
1
  /*    */  {50,           0,        0,      255},   //!< temp_boost_setpoint_diff, unit 0,01°C
2
  /*    */  {10,           0,        0,      255},   //!< temp_boost_hystereses, unit 0,01°C 
3
  /*    */  {30,           0,        0,      255},   //!< temp_boost_error, unit 0,01°C
4
  /*    */  {15,           0,        0,      255},   //!< temp_boost_time, minutes


controller.c 150
1
    if ( minute_ch && (PID_boost_timeout>0)) {  //timeout in minutes (15)
2
    PID_boost_timeout--;
3
      if (PID_boost_timeout==0) {
4
      PID_force_update = 0;
5
      }
6
    }
        if (updateNow) {
1
//jr needed in PID update, so set it later      CTL_temp_wanted_last=temp;
2
      goto UPDATE_NOW; // optimize
        valveHistory[0]=new_valve;
      }
1
      CTL_temp_wanted_last=temp;  //jr was after line "if (updateNow) {" before
        }
       COM_print_debug(0);


controller.c ~310:
    if (updateNow) {
      CTL_interatorCredit=config.I_max_credit;
      CTL_creditExpiration=config.I_credit_expiration;
      CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK; // do not allow 
update integrator immediately after temp change
      testIntegratorRevert(lastAbsError);
      lastTempChangeErrorAbs = absErr;
      lastTempChangeSumError = sumError;
1
      if ((PID_boost_timeout==0) && (abs(setPoint-CTL_temp_wanted_last)>=config.temp_boost_setpoint_diff) // change of wanted temp large enough to start boost (0,5°C)
2
        && (absErr>=(int16_t)config.temp_boost_error)) {  // error large enough to start boost (0,3°C)
3
        PID_boost_timeout = config.temp_boost_time; // temp_boost_time in minutes
      }
    } else {

controller.c ~360:
  }
  lastProcessValue = processValue;
1
  if ((PID_boost_timeout > 0) && //choose position of code, because parameters like error are calculated above
2
    (abs(error16)<=(int16_t)(config.temp_boost_error-config.temp_boost_hystereses))) {  // error <= temp_boost_error-temp_boost_hystereses
3
    PID_boost_timeout=0; // end boost earlier, if error got to small (0,2°)
4
  }
5
  if (PID_boost_timeout > 0) {  // boost active
6
  CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK;       //block Integrator
7
    if (error16>0) {
8
      return config.valve_max;   //boost to max, no PID calculation
9
    } else {
10
      return config.valve_min;   //boost to min, no PID calculation
11
  }
  }

  if (config.I_Factor > 0) {

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
@Chris any new ideas about bat ADCprob ?? I am having it again ...

von Richard G. (gggggg)


Rate this post
useful
not useful
looks like adc meaeures x01bb all the time. But after reset (just by 
programming fuses) the same value is interpreted differently:
1
batAD x01bb
2
batAD x01bb
3
D: d5 01.01.10 12:00:22 A V: 30 I: 2274 S: 1700 B: 2542 Is: 00000000 Ib: 06 Ic: 28 bo: ff E
4
batAD x01bb
5
batAD x01bb
6
batAD x01bb
7
batAD x01bb
8
batAD x01bb
9
batAD x01bb
10
batAD x01bb
11
batAD x01bb
12
D V:OpenHR20 (3*16+3).( 5*16+4) Apr  3 2011 12:33:06 101
13
V:OpenHR20 (3*16+3).( 5*16+4) Apr  3 2011 12:33:06 101
14
V:OpenHR20 (3*16+3).( 5*16+4) Apr  3 2011 12:33:06 101
15
batAD x01bb
16
batAD x01bb
17
batAD x01bb
18
batAD x01bb
19
batAD x01bb
20
batAD x01bb
21
batAD x01bb
22
batAD x01bb
23
batAD x01bb
24
batAD x01bb
25
batAD xbat
26
batAD x01bb
27
D
28
batAD x01bb
29
batAD x01bb
30
batAD x01bb
31
D: d5 01.01.10 12:00:21 A V: 80 I: 0000 S: 1700 B: 0000 Is: 00000000 Ib: 06 Ic: 28 bo: ff X
32
batAD x01bb
33
batAD x01bb
34
batAD x01bb
35
D
36
batAD x01bb
37
D: d5 01.01.10 12:00:25 A V: 80 I: 2267 S: 1700 B: 3728 Is: 00000000 Ib: 06 Ic: 28 bo: ff E:04 X
38
batAD x01bb

von Richard G. (gggggg)


Rate this post
useful
not useful
@Jiri: still dont look through the ring buffer secrets ... but is it 
possible that this
static void shift_ring(void) {
#if ! HW_WINDOW_DETECTION
  ring_pos = (ring_pos+1) % AVERAGE_LEN;

should look like that ????
static void shift_ring(void) {
  ring_pos = (ring_pos+1) % AVERAGE_LEN;
#if ! HW_WINDOW_DETECTION

von Richard G. (gggggg)


Rate this post
useful
not useful
deleted

von Richard G. (gggggg)


Rate this post
useful
not useful
average is definitely miscalculated: istead of 9b6 we get ee4
AV is calculated average, followed by the 15 values aof ring buffer

AV0ee4

009b6
109b6
209b6
309bc
409b6
509b6
609b6
709b6
809b6
909b6
A09b6
B09b6
C09b6
D09b6
E09b6

von Richard G. (gggggg)


Rate this post
useful
not useful
Should this:
static void update_ring(uint8_t type, int16_t value) {
  ring_sum[type]+=value;

better look like that:
static void update_ring(uint8_t type, int16_t value) {
  ring_sum[type]+=(int32_t)value;

It looks like sum is calculated wrong.. SUm is e910  this is 18 * 09b6
SUe910
AV0f89
009b6
109b6
209b6
309b6
409b6
509b6
609b6
709b6
809b6
909b6
A09b6
B09b6
C09b6
D09b6
E09b6

von Richard G. (gggggg)


Rate this post
useful
not useful
OK so the bugs are = corrected bugs look like:
a) static uint8_t ring_used=0;

b)
static void shift_ring(void) {
  ring_pos = (ring_pos+1) % AVERAGE_LEN;
#if ! HW_WINDOW_DETECTION


c)
  ring_sum[type]+=(int32_t)value;
  ring_sum[type]-=(int32_t)ring_buf[type][ring_pos];
  if (ring_used>=AVERAGE_LEN) {


The main reason is that update_ring is called more often than shif_ring 
during the phase were ring_used is less than average_len

d) Another question:
switch (++state_ADC) means präfix ++

is this OK then for noise protection:
 state_ADC=3;
 state_ADC=5;

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
my preliminary adc.c - see attachement

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
in attachement find next step preliminary boost function with time 
calculation.
description http://embdev.net/topic/118781?goto=2130451#2129904

von Jiri D. (jdobry)


Rate this post
useful
not useful
I found, where was battery measurement problem. Normally it call 
update_ring twice (one for battery, one for temperature). And shift_ring 
only once after measure finish. But noise cancellation loop can cause, 
that measurement repeats many time and next second pulse come earlier. 
It restart measures. It repeat update_ring without shift_ring and this 
situation with (ring_used<AVERAGE_LEN) create this problem.
Fixed in rev 355, change is here: 
http://openhr20.svn.sourceforge.net/viewvc/openhr20/rfmsrc/OpenHR20/adc.c?r1=355&r2=354&pathrev=355

von Jiri D. (jdobry)


Rate this post
useful
not useful

von Jiri D. (jdobry)


Rate this post
useful
not useful
Option BOOST_CONTROLER_AFTER_CHANGE added.
Richard, please check it (contain one small difference to your code)

http://openhr20.svn.sourceforge.net/viewvc/openhr20?view=revision&revision=357

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, THX
d) Another question:
switch (++state_ADC) ..... ++ here means increment before operation !!
is this OK then for noise protection:
 state_ADC=3;
 state_ADC=5;

I will check the new code tommorow ...

BTW: After 10-15 hours I had this error today .. what is the typical 
reason for ir ?
1
    if (motor_timer>0) { // normal stop on wanted position 
2
            if (MOTOR_calibration_step != 0) {
3
                MOTOR_calibration_step = -1;     // calibration error
4
                CTL_error |=  CTL_ERR_MOTOR;
5
                CTL_error_jr =  1; //jr CTL_ERR_MOTOR;

von Jiri D. (jdobry)


Rate this post
useful
not useful
(++state_ADC) is correct, next call not execute step 3(5) but 4(6)

Reason for your error is overload maximum volume of pulses during 
calibration. (see to MOTOR_MAX_IMPULSES)

von Jiri D. (jdobry)


Rate this post
useful
not useful
Battery voltage error fix was not complete. Updated.

von Richard G. (gggggg)


Rate this post
useful
not useful
"Reason for your error is overload maximum volume of pulses during
calibration. (see to MOTOR_MAX_IMPULSES)"

Can it be another reason, because there was no clalib sceduled after 
valve was installed ????
- Maybe it started calib for another reason (not saturday 10:00) - why 
would it do that ???
- It might have something to do with the boostfunction. It moves valve 
to MAX and later back to MIN ????

von Richard G. (gggggg)


Rate this post
useful
not useful
R359 THX Jiri:
1.adc I dont understand the -1, because we want to fill all 15 
positions(0-14) before we calc average. ring_used runs as ring_pos from 
0 to 15 !!!
With -1 we start calculating after 14 (pos=0-13) entries. So pos[14] is 
still=0. This way the first calculated average will be wrong ???
if (ring_used>=AVERAGE_LEN-1) { // note for "-1", last measurement can 
update ring_average

2.controller line 171 has to be moved after line 200, because 
boostdedection needs temp_wanted last see line ~334
        valveHistory[0]=new_valve;
line 200      }
1
      CTL_temp_wanted_last=temp;  //jr was after line "if (updateNow) {" before
        }
       COM_print_debug(0);

3. See last post. I still dont understand where my E3 can come from. As 
I marked the different E3 errors with E31-E34, it must be the one I 
posted... Why should it calibrate ? why should this gi wrong then ? Low 
Voltage on a long valve move ???

von Jiri D. (jdobry)


Rate this post
useful
not useful
1. It is simple. In this case, we have 15 complete measurement. In table 
(0-14), ring_pos=ring_used=14. But ring_used will be incremented later. 
It is reason to compare with 14, not 15.

2. Changed in Rev 360

3. calibration is not start after set position to min or max. I start 
after valve mount  reboot  every Sat 10:00 Never else. And see to 
condition for this error (MOTOR_calibration_step != 0) it means 
calibration on progress or calibration error before this.

von Richard G. (gggggg)


Rate this post
useful
not useful
New idea for reverting:
Build a moving average of sumerror from max. n(should last for a week or 
so...e.g. 255) values. Only use an sumerror for average, if error is 
small (<0,3) and stable.
Average is built only after update (typ. 1-4x per day). I need your help 
on a simple idea to handle it like the temp_ring_average !!

    if (updateNow) {
      CTL_interatorCredit=config.I_max_credit;
      CTL_creditExpiration=config.I_credit_expiration;
      CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK; // do not allow 
update integrator immediately after temp change
      testIntegratorRevert(lastAbsError);
1
      if ((absErr==lastAbsError) && (absErr<(I_ERR_TOLLERANCE_AROUND_0<<1)) //stable error & error < 0,3°C)
2
        && (average_sumerr_count<=255) ) {
3
      average_sumerr_count++;
4
      lastTempChangeSumError += (sumError-lastTempChangeSumError)/average_sumerr_count; //average of sumerrors
5
      }
      lastTempChangeErrorAbs = absErr;


Revert only is done, if the error could not be reduced by 25% and the 
error is larger than 3.g. 0,3°C
1
static void testIntegratorRevert(uint16_t absErr) {
2
  if (absErr>=(lastTempChangeErrorAbs>>2*3) && absErr > (I_ERR_TOLLERANCE_AROUND_0<<1)) {
3
  // if error could not be reduced to 3/4 and Error is larger than 0,3°C
4
  // if (absErr>=(lastTempChangeErrorAbs/2)) {
5
    // revert Integrator to previous state if current error is not smaller than 1/2  of original
6
    sumError=lastTempChangeSumError;
7
  }
8
  lastTempChangeErrorAbs = 0xffff; // function can be called more time but only first is valid
9
}

von Jiri D. (jdobry)


Rate this post
useful
not useful
Richard:
first - we don't have space for average buffer (used 685 bytes (66.9% 
Full) but without unknown stack size on top)

second - something like "stable" error not exist. See here to real data 
http://embdev.net/attachment/102842/1.png

third - exist only one correct way. This mean make model function and 
use regression analysis to find unknown parameters on real time.

von Jiri D. (jdobry)


Rate this post
useful
not useful
testIntegratorRevert is updated

note: price of this change is 80bytes in flash (0.5% of size)

von Richard G. (gggggg)


Rate this post
useful
not useful
OK,
1. of course I am looking forward to your math model !!
I know that there is no real stable error....
Actually  the posted version works without ringbuffer anyway (less 
code). But I have to think about a better moving of the average... right 
now moving stops after 255 values...


2. in line 308 it was (I_ERR_TOLLERANCE_AROUND_0<<1). This way it only 
revert on errors >= 0,3°C ...


3. Jiri why did you solve that with so many #if #else ?? is it less code 
? Because this simple change based on 359 was easier to undestand (for 
me;-) ...
1
        if (updateNow) {
2
//jr needed in PID update, so set it later      CTL_temp_wanted_last=temp;
3
      goto UPDATE_NOW; // optimize
4
    }
5
        if ((PID_update_timeout == 0)) {
6
      UPDATE_NOW:
7
            PID_update_timeout = (config.PID_interval * 5); // new PID pooling
8
      uint8_t new_valve;
9
                new_valve = config.valve_max;
10
            } else {
11
                new_valve = pid_Controller(calc_temp(temp),temp_average,valveHistory[0],updateNow);
12
            }
13
      {  
14
        int8_t i;
15
        #if BLOCK_INTEGRATOR_AFTER_VALVE_CHANGE
16
          if (valveHistory[0]!=new_valve) {  
17
            CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK;       //block Integrator if valve moves
18
          }
19
        #endif
20
21
        for(i=VALVE_HISTORY_LEN-1; i>0; i--) {
22
          if (updateNow || (new_valve <= config.valve_max) || (new_valve >= config.valve_min)) {
23
            // condition inside loop is stupid, but produce shorter code
24
            valveHistory[i]=new_valve;
25
          } else  {
26
            valveHistory[i]=valveHistory[i-1];
27
          }
28
        }
29
        valveHistory[0]=new_valve;
30
      }
31
      CTL_temp_wanted_last=temp;  //jr was after line "if (updateNow) {" before

von Jiri D. (jdobry)


Rate this post
useful
not useful
2. ???? Where is problem ?

3. I know that it is little bit complicated. But try it and you will see 
difference in code size. This code is significantly smaller for 
BLOCK_INTEGRATOR_AFTER_VALVE_CHANGE = 0

von Richard G. (gggggg)


Rate this post
useful
not useful
ad2) I_ERR_TOLLERANCE_AROUND_0
1
<<1
 missing

von Jiri D. (jdobry)


Rate this post
useful
not useful
<<1 why?

von Jiri D. (jdobry)


Rate this post
useful
not useful
"<<1" opps, I see, fixed

von Richard G. (gggggg)


Rate this post
useful
not useful
a) I am curious why you used *2: Does <<1 not work with constants ?
another C thing:
b) When do we declare variables "static" in HR20
c) is an "extern" declared variable automatically "static" ? example is 
"lastTempChangeSumError" is static, but as I wanted it beeing sent over 
COM I had to declare it extern ...

von Richard G. (gggggg)


Rate this post
useful
not useful
deleted

von Jiri D. (jdobry)


Rate this post
useful
not useful
a) *2 is better for reading. Because is is constant, it is not need 
optimize it for execution.

b) "static" is for local only variables and function. "static" function 
have one more benefit, it can be linked into call point and it is nice 
for compiler optimization.

c) if you need use variable or function outside "C" file it can't be 
static.

von Richard G. (gggggg)


Rate this post
useful
not useful
THX:
     #if ! BOOST_CONTROLER_AFTER_CHANGE
      if (updateNow) {
1
172 CTL_temp_wanted_last=temp;
     ...
    #else
      if (updateNow||(PID_update_timeout == 0)) {
    #endif
            PID_update_timeout = (config.PID_interval * 5);
            uint8_t new_valve;
            if (temp>TEMP_MAX) {
                new_valve = config.valve_max;
            } else {
                new_valve = 
pid_Controller(calc_temp(temp),temp_average,valveHistory[0],updateNow);
            }
1
187 #if BOOST_CONTROLER_AFTER_CHANGE
1
188 if (updateNow) {
1
189  CTL_temp_wanted_last=temp;
        }
     #endif

Jiri,
a) I think line 172 (CTL_temp_wanted_last=temp;) can be at the end 
=line189 in both cases... (I checked that already)

b) so we can also forget the #if from 187

c) and the if in 188 is not needed. It does not matter if 
CTL_temp_wanted_last is set under any condition more often...

von Jiri D. (jdobry)


Rate this post
useful
not useful
OK I clean up this code.
note: price of moving "CTL_temp_wanted_last=temp;" line is 8 bytes. We 
has code bigger than flash already. Current code uses MANY hack to 
optimization.

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri you can also keep it, your decision, I can live with it,

Then just delete the if from line 188...

von Richard G. (gggggg)


Rate this post
useful
not useful
THX Jiri

R362:
Program:   13398 bytes (81.8% Full)
Data:        485 bytes (47.4% Full)
EEPROM:      392 bytes (76.6% Full)

R363:
Program:   13392 bytes (81.7% Full)

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, I had this E31 error again - please comment on this

When I mounted the valve it was nearly fully open (12 pulses) .. when 
the error came up it was fully closed (i nearly could not move it any 
further by hand)
Values when E31 came up:
MOTOR_PosMax=12
MOTOR_PosAct=fde9
MOTOR_PosOvershoot=1
MOTOR_counter=23b

The next time calib was OK:
MOTOR_PosMax=2c6

von Jiri D. (jdobry)


Rate this post
useful
not useful
R363 with RFM and normal "wheel" settings
1
Program:   16022 bytes (97.8% Full)
2
Data:        690 bytes (67.4% Full)
3
EEPROM:      400 bytes (78.1% Full)

but with CTL_temp_wanted_last=temp; like previous versions
1
Program:   16014 bytes (97.7% Full)

16022 means 362bytes free and it is less than 181 AVR machine 
instructions.
Not nice.

von Richard G. (gggggg)


Rate this post
useful
not useful
I think we could save some bytes, because with I_ERR_TOLLERANCE_AROUND_0 
we have covered this good enough ...
if ((error16 >= 0) ? (old_result < config.valve_max) : (old_result > 
config.valve_min)) {
1
        if (  // ((lastErrorSign != ((uint8_t)(error16>>8)&0x80)))
2
||  //sign of last error16 != sign of current
        ((absErr==lastAbsError) && (absErr<=I_ERR_TOLLERANCE_AROUND_0))) 
{  //abserror around 0

and please set the error variables to an invalid value and they have to 
be different

please comment on my E31 from above

von Richard G. (gggggg)


Rate this post
useful
not useful
the post timed out...  and please set the error variables to an invalid 
value and they have to be different:
static uint16_t lastAbsError = 0xFF;  //set invalid
static uint16_t last2AbsError= 0xFE;  //set invalid and different to 
lastAbsError

von Jiri D. (jdobry)


Rate this post
useful
not useful
E31 means here ?
1
   if (motor_timer>0) { // normal stop on wanted position 
2
            if (MOTOR_calibration_step != 0) {
3
                MOTOR_calibration_step = -1;     // calibration error
4
                CTL_error |=  CTL_ERR_MOTOR;
5
            }

Strange. MOTOR_PosMax-MOTOR_PosAct = 552[dec]
But mininum posion for this error is  (MOTOR_PosMax-MOTOR_MAX_IMPULSES) 
= -982 = 0xFC2A And this position was not reach.

Motor stops in 2 conditions:
- reach to final positon (not happen)
- motor slow down or stop mechanicaly, but in this condition is 
motor_timer==0

This mean, that it can't be this error, or we have some bug in code.
what was in motor_diag (trace variable 0x05)

von Richard G. (gggggg)


Rate this post
useful
not useful
if (motor_timer>0) { // normal stop on wanted position
            if (MOTOR_calibration_step != 0) {
                MOTOR_calibration_step = -1;     // calibration error
                CTL_error |=  CTL_ERR_MOTOR;
                CTL_error_jr =  1; //jr CTL_ERR_MOTOR;
menu.c ...E35 is spare
1
                } else if (CTL_error & CTL_ERR_MOTOR) {
2
                    if      (CTL_error_jr==1) { 
3
            LCD_PrintStringID(LCD_STRING_E31,LCD_MODE_ON); 
4
           } else if (CTL_error_jr==2) { 
5
             LCD_PrintStringID(LCD_STRING_E32,LCD_MODE_ON); 
6
           } else if (CTL_error_jr==3) { 
7
             LCD_PrintStringID(LCD_STRING_E33,LCD_MODE_ON); 
8
           } else if (CTL_error_jr==4) { 
9
             LCD_PrintStringID(LCD_STRING_E34,LCD_MODE_ON); 
10
           } else if (CTL_error_jr==5) { 
11
             LCD_PrintStringID(LCD_STRING_E35,LCD_MODE_ON);
12
           } 
13
                } else if (CTL_error & CTL_ERR_BATT_WARNING) {
LCD.c... in any language
      {32,14, 3, 1},    //!<  " E31"    LCD_STRING_E31
      {32,14, 3, 2},    //!<  " E32"    LCD_STRING_E32
      {32,14, 3, 3},    //!<  " E33"    LCD_STRING_E33
      {32,14, 3, 4},    //!<  " E34"    LCD_STRING_E34
      {32,14, 3, 5},    //!<  " E35"    LCD_STRING_E35
      {32,14, 4,32},    //!<  " E4 "    LCD_STRING_E4

it is this code position for sure 99,99% ... I used the motor diag watch 
for something else ;-)

it seems like it happens only after I flashed a new programm and had the 
batteries out ... can this be a trace ??

von Richard G. (gggggg)


Rate this post
useful
not useful
I just tried to dismount, batteries out/in, remount 5 times ... no error

von Richard G. (gggggg)


Rate this post
useful
not useful
when calib goes OK. motor_diag on this valve runs typ at 5c0 and at the 
close position it is 784

von Jiri D. (jdobry)


Rate this post
useful
not useful
OK. But what is E31?

von Richard G. (gggggg)


Rate this post
useful
not useful
I have 4 different error messsages for the 4 different code lines of E3 
(E31-E34  see last posts)

E31:
if (motor_timer>0) { // normal stop on wanted position
            if (MOTOR_calibration_step != 0) {
                MOTOR_calibration_step = -1;     // calibration error
                CTL_error |=  CTL_ERR_MOTOR;
1
                CTL_error_jr =  1; //jr CTL_ERR_MOTOR E3(1)
...menu.c
                } else if (CTL_error & CTL_ERR_MOTOR) {
1
                    if      (CTL_error_jr==1) {
2
            LCD_PrintStringID(LCD_STRING_E31,LCD_MODE_ON);

Any idea how I can reproduce the prob. ??

von Jiri D. (jdobry)


Rate this post
useful
not useful
see to my post from 2011-04-08 16:51

von Richard G. (gggggg)


Rate this post
useful
not useful
1. I think we could save some bytes, because with 
I_ERR_TOLLERANCE_AROUND_0
we have covered the sign change as well ... delete highlighted line
if ((error16 >= 0) ? (old_result < config.valve_max) : (old_result >
config.valve_min)) {
  if (
1
 // ((lastErrorSign != ((uint8_t)(error16>>8)&0x80))) ||  
2
         //sign of   last error16 != sign of current
     ((absErr==lastAbsError) && (absErr<=I_ERR_TOLLERANCE_AROUND_0))) { 
//abserror around 0

2. please initialize the error variables with an invalid
value and they have to be different:
1
static uint16_t lastAbsError = 0xFF;  //set invalid
2
static uint16_t last2AbsError= 0xFE;  //set invalid and different to
3
lastAbsError

3. I use a moving average for reverting ... this way the problem of 
short periodes (some days, depending on I_SUMERR_CHANGE_WEIGHT ) with no 
heating looks quite well ...

    if (updateNow) {
      CTL_interatorCredit=config.I_max_credit;
      CTL_creditExpiration=config.I_credit_expiration;
      CTL_integratorBlock=DEFINE_INTEGRATOR_BLOCK; // do not allow 
update integrator immediately after temp change
      testIntegratorRevert(lastAbsError);
      if ((lastAbsError==last2AbsError) && 
(lastAbsError<(I_ERR_TOLLERANCE_AROUND_0*2))) {//stable error & error < 
0,3°C)
1
      lastTempChangeSumError += (sumError-lastTempChangeSumError)/I_SUMERR_CHANGE_WEIGHT; 
2
      //imapct of SumErr changes on lastSummError, averaging for integrator revert
      }
      lastTempChangeErrorAbs = absErr;
      // lastTempChangeSumError = sumError;

#define I_SUMERR_CHANGE_WEIGHT 10  // impact on lastSumError which is 
used for reverting

von Jiri D. (jdobry)


Rate this post
useful
not useful
1) I thing that it is not covered, this is reason : 
(absErr==last2AbsError). See here 
http://embdev.net/attachment/102842/1.png
Except this I thing that zero cross is better than something 
with(absErr==last2AbsError)

2) You are right, it is best practice. But because situation in flash 
space is critical, I will use it only if it really needed. I thing, that 
0 not make any problem.

3) Why? You don't need make any average from stable value. If this value 
is not almost stable, something is wrong. We need solve causation, not 
mask result.

von Richard G. (gggggg)


Rate this post
useful
not useful
ad1) (absErr==last2AbsError) this prevents, that we give credit, if 
temperature rushes up/down = ext. influence. In your example I guess it 
was P part and not integrator moving the valve. So a fast change of sign 
should not be handled by I-part and a slow change is covered by 
"dedection around 0"... I live quite well for a while without the sign 
dedection, but loosened the restriction (absErr==last2AbsError) to 
(absErr==lastAbsError)...

ad2) well, directly after boot, temp is updated and comparisons like 
this go wrong then.. but I can live with that ... your decison...
if ((lastAbsError==last2AbsError) && 
(lastAbsError<(I_ERR_TOLLERANCE_AROUND_0*2))) {//stable error & error < 
0,3°C)
        // && (average_sumerr_count<255) ) {

ad3) Because right now - in times where heating is deactivated temporary 
by high outside temps during day or night ... the actual code
lastTempChangeSumError = sumError;

produces more wrong reactions (I-parts) than a continous averaging:
lastTempChangeSumError += 
(sumError-lastTempChangeSumError)/I_SUMERR_CHANGE_WEIGHT;  // weight 
e.g.=10

I thik this is a compromise (with liitle code) until we find a better 
(math) solution for revert

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
here is a quick status from my side which includes:
NO_AUTORETURN_FROM_ALT_MENUES=-DNO_AUTORETURN_FROM_ALT_MENUES=1
BLOCK_INTEGRATOR_AFTER_VALVE_CHANGE=-DBLOCK_INTEGRATOR_AFTER_VALVE_CHANG 
E=1
BOOST_CONTROLER_AFTER_CHANGE=-DBOOST_CONTROLER_AFTER_CHANGE=1
and a modified code for reverting (posted above, value Isl in the chart)
Valve MAX=80, MIN=CENTER=52, Credit_expiration=255

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
I changed MAX to 96 around 13:00, 80% did not open the valve wide 
enough. This way boost function works more effective.. room gets warmer 
about 0,7° within 1 hour ... during this valve reverted SumError=Is 
(vlack line) to lastSumError=Isl (moving average with 10% impact of 
SumError ... see black dotted line)
Heating was OFF from 22:00-4:30..

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
@Jiri:
I found some bugs in my code (BOOST) and deleted unnecessary EEprom 
variables ...
Could you please integrate the changes from OpenHR20_R363_mod110417.zip 
in a new revision ... THX

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
Jiri:
I mailed the changes to you... as your mailbox seems to be full I add 
the .zip here ...

von Richard G. (gggggg)


Rate this post
useful
not useful
Also my last MAil returned .. so I post the changes here: The files are 
zipped in my last post ;-)
1
com.c 309
2
 print_s_p(PSTR(" bo: ")); //jr
3
 print_hexXX(PID_boost_timeout);
4
 print_s_p(PSTR(" Iac ")); //jr
5
 print_hexXX(average_sumerr_count);
6
 print_s_p(PSTR(" Isl "));
7
 print_hexXXXX(lastTempChangeSumError>>16); //jr
8
 print_hexXXXX(lastTempChangeSumError); //jr
9
10
controller.c:
11
60:
12
#if BOOST_CONTROLER_AFTER_CHANGE
13
 uint8_t PID_boost_timeout;  //boost timout in minutes
14
 uint8_t PID_boost;  //boost value, either valve max or min
15
#endif
16
17
183: cosmetic:
18
      CTL_integratorBlock=CTL_INTEGRATOR_BLOCK;       //block Integrator if valve moves
19
20
 
21
248:
22
   PID_boost_timeout = 0; //to disable boost change mode, then change setpoint and change back mode
23
24
271:
25
static uint16_t lastAbsError = 0xFF;  //set invalid
26
static uint16_t last2AbsError= 0xFE;  //set invalid and different to lastAbsError
27
28
290:
29
static uint16_t lastTempChangeErrorAbs=0xffff;
30
int32_t lastTempChangeSumError=0;
31
uint8_t average_sumerr_count=0; // counting # of averages, just for diagnosis purposes
32
33
296: just comment:
34
  // if error could not be reduced to 3/4 and Error is larger than I_ERR_TOLLERANCE_AROUND_0*2 °C
35
36
320:
37
    CTL_integratorBlock=CTL_INTEGRATOR_BLOCK; // do not allow update integrator immediately after temp change
38
    testIntegratorRevert(lastAbsError);
39
    if ((lastAbsError==last2AbsError) && (lastAbsError<(I_ERR_TOLLERANCE_AROUND_0*2))) {//stable error & error < 0,3°C)
40
     average_sumerr_count++;  //just for diagnosis, how often do we average
41
   lastTempChangeSumError += (sumError-lastTempChangeSumError)/I_SUMERR_CHANGE_WEIGHT; 
42
   //imapct of SumErr changes on lastSummError, averaging for integrator revert
43
    }
44
    lastTempChangeErrorAbs = absErr;
45
    // lastTempChangeSumError = sumError;
46
    #if BOOST_CONTROLER_AFTER_CHANGE
47
       PID_boost_timeout = 0;
48
     if (absErr>=(int16_t)config.temp_boost_error) {  // error large enough to start boost (0,3°C)
49
    if (error16 >= 0) {
50
     PID_boost = config.valve_max;
51
     PID_boost_timeout = config.temp_boost_time_heat;
52
    } else {
53
     PID_boost = config.valve_min;
54
     PID_boost_timeout = config.temp_boost_time_cool;
55
    }
56
    PID_boost_timeout = (uint8_t)(MIN(255,abs(error16)/10*(int16_t)PID_boost_timeout/CTL_BOOST_TEMPCHANGE)); //boosttime=error/10(0,1°C)*time/CTL_BOOST_TEMPCHANGE(0,5°C)
57
     }       
58
59
340:
60
 this prevents, that we give credit, if temperature rushes up/down = ext. influence. In your posted example I guess it was P part and not integrator moving the valve. So a fast change of sign should not be handled by I-part and a slow change is covered by "dedection around 0"... I live quite well for a while without the sign
61
dedection
62
    if (  // ((lastErrorSign != ((uint8_t)(error16>>8)&0x80))) ||  //sign of last error16 != sign of current
63
    ((absErr==last2AbsError) && (absErr<=I_ERR_TOLLERANCE_AROUND_0))) {  //abserror around 0 with slow change
64
      CTL_interatorCredit=config.I_max_credit; 
65
66
370:
67
  #if BOOST_CONTROLER_AFTER_CHANGE
68
 if (PID_boost_timeout > 0) {
69
  CTL_integratorBlock=CTL_INTEGRATOR_BLOCK;       //block Integrator
70
  CTL_creditExpiration=config.I_credit_expiration;
71
  return PID_boost;  //return valve_MAX or MIN
72
 }
73
  #endif
74
75
 
76
 
77
eeprom.h:
78
~100:
79
#if BOOST_CONTROLER_AFTER_CHANGE
80
 /*    */ uint8_t  temp_boost_error;
81
 /*    */ uint8_t  temp_boost_time_cool;
82
 /*    */ uint8_t  temp_boost_time_heat;
83
#endif
84
 
85
~250:
86
#if BOOST_CONTROLER_AFTER_CHANGE
87
  /*    */  {30,          30,       10,      255},   //!< temp_boost_error,start boost if error to new setpoint is larger than this,unit0,01°C
88
  /*    */  {64,          64,        0,      255},   //!< temp_boost_time_cool, minutes boost should last during heat up, if error = CTL_BOOST_TEMP_CHANGE(0,5°C)
89
  /*    */  {48,          48,        0,      255},   //!< temp_boost_time_heat, minutes boost should last during cool down, if error = CTL_BOOST_TEMP_CHANGE(0,5°C)
90
#endif
91
92
controller.h 
93
~63:
94
#define CTL_INTEGRATOR_BLOCK 6    //jr was=6
95
#define I_ERR_TOLLERANCE_AROUND_0 15 // unit 0,01°C. Set it quite restrictive !
96
#define I_ERR_WEIGHT 25 //impact of error on I part
97
#define I_SUMERR_CHANGE_WEIGHT 10 //imapct of SumErr changes on lastSummError, averaging for integrator revert
98
#define CTL_BOOST_TEMPCHANGE 5 //unit 0,1°C, estimated change of temp during boosttime, for calculating boost time
99
100
80:
101
extern uint8_t PID_boost_timeout;
102
extern uint8_t CTL_creditExpiration;
103
extern int32_t lastTempChangeSumError;
104
extern uint8_t average_sumerr_count;
105
106
motor.c: 111
107
        CTL_integratorBlock=CTL_INTEGRATOR_BLOCK;
108
109
watch.c:
110
    /* 00 */ ((uint16_t) &sumError) + B16,
111
    /* 01 */ ((uint16_t) &CTL_integratorBlock) + B8,
112
    /* 02 */ ((uint16_t) &CTL_interatorCredit)+ B8,
113
    /* 03 */ ((uint16_t) &PID_boost_timeout)+ B8,
114
 /* 04 */ ((uint16_t) &average_sumerr_count) + B8,
115
    /* 05 */ ((uint16_t) &lastTempChangeSumError) + B16,
116
 /* 06 */ ((uint16_t) &MOTOR_PosMax) + B16,  //12  az:2c6 bad:22c 
117
 /* 07 */ ((uint16_t) &MOTOR_PosAct) + B16,  //fde9  az:18d bad:c4
118
 /* 08 */ ((uint16_t) &MOTOR_PosOvershoot) + B8, //1
119
#if DEBUG_MOTOR_COUNTER
120
 /* 09 */ ((uint16_t) &MOTOR_counter) + B16,  //23b
121
 /* 04 */ ((uint16_t) &motor_diag) + B16,
122
// /* 0a */ ((uint16_t) &MOTOR_counter)+ 2 + B16, //0
123
#endif

von Richard G. (gggggg)


Rate this post
useful
not useful
Hi Jiri - are you still there ? - I would like to finish up, before the 
summer comes and I forget everything .... ;-)
RE: "Can you generate "diff" file? (for ex in TortoiseSVN)"
Sorry, no know how in those things ...
a) either you instruct me or
b) I could also edit the changes into R363 files and send you those ..

von jdobry (Guest)


Rate this post
useful
not useful
I am still here. But I am too busy on another tasks till end of may.

von Richard G. (gggggg)


Rate this post
useful
not useful
Ok .. then we'll clean up end of May/June ... BR .. Richard

von transis (Guest)


Rate this post
useful
not useful
Need some help. I receive following error msg during compiling:

**** Build of configuration Debug for project HR20 ****

make all
Building file: ../src/lcd.c
Invoking: AVR Compiler
avr-gcc -Wall -g2 -gstabs -O0 -fpack-struct -fshort-enums -std=gnu99 
-funsigned-char -funsigned-bitfields -mmcu=atmega169p -DF_CPU=1000000UL 
-MMD -MP -MF"src/lcd.d" -MT"src/lcd.d" -c -o "src/lcd.o" "../src/lcd.c"
../src/lcd.c: In function 'LCD_HourBarBitmap':
../src/lcd.c:627: error: r28 cannot be used in asm here
../src/lcd.c:627: error: r29 cannot be used in asm here
make: *** [src/lcd.o] Error 1

**** Build Finished ****

lcd.c revison: 192
how can i fix this error(s)?

von Jiri D. (jdobry)


Rate this post
useful
not useful
transis: Which compiler? Please try WinAVR-20100110.

von transis (Guest)


Rate this post
useful
not useful
it is already the compiler: WinAVR-20100110 !

von transis (Guest)


Rate this post
useful
not useful
I've also tried to compile it with AVR-Studio 5 => same compiler 
error(s):

Error 1 r28 cannot be used in asm here ...\lcd.c 627 1  OpenHR20
Error 2  r29 cannot be used in asm here ...\lcd.c 627 1  OpenHR20

von transis (Guest)


Rate this post
useful
not useful
Error:
   ../src/lcd.c:627: error: r28 cannot be used in asm here
   ../src/lcd.c:627: error: r29 cannot be used in asm here

Fix-Proposal:
   modify line in lcd.c
   from:
     : "r14", "r15", "r16", "r28","r29", "r30", "r31"
   to:
     : "r14", "r15", "r16", "r30", "r31"

after this modification the compilaton will pass.

What are the side-effects of this fix?
(I'm not so experienced with assembler coding ...)

von jdobry (Guest)


Rate this post
useful
not useful
Problem is that this line not create any code. It just inform compiler 
optimizer about used registers. If you remove it, ASM code rewrite this 
registers and compiler will not know it. It will fail.
Are you sure that in compilation you use  WinAVR-20100110 ? It is tested 
with this without problem.

von transis (Guest)


Rate this post
useful
not useful
yes, i am sure. It is the compiler "WinAVR-20100110"! But this errors 
was also reported by AVR-Studio5. I think it is not a compiler specific 
problem.

von transis (Guest)


Rate this post
useful
not useful
Hello again,

I've tried to compile it with "release" setup, and it is 
compiling.(Before, it was in the "debug" setup => with this setup i got 
the above mentioned errors.)

are the compiling options wrong?
release-setup:
   avr-gcc -Wall -Os  ...
debug-setup:
   avr-gcc -Wall -g2 -gstabs -O0 ...

von transis (Guest)


Rate this post
useful
not useful
After some further testing....
The parameter/option "-O0" raise this errors. When i am select one of 
the other optimization levels "-O1..3" the errors are not occured.

Can someone explain me this crazy behavior?

von Marco G. (stan)


Rate this post
useful
not useful
Hi,
-O0 means no optimization, so it seems that without optimization these 
two registers are necessary for the C code and then the compiler 
complains.

von transis _. (Company: manmen) (transis)


Rate this post
useful
not useful
sounds plausible. ;-)

What will be the workaround/fix (is it a bug?)
Why this error was only reported/seen by me (i think the compilers with 
same options should report same errors...)?

von jdobry (Guest)


Rate this post
useful
not useful
I any way, compile it for debug with -O0 have not solution. Simply 
before code will be too big for only 16kB flash.

von Richard G. (gggggg)


Rate this post
useful
not useful
jdobry wrote:
> I am still here. But I am too busy on another tasks till end of may.

Hi Jiri, hope you have/had a good summer ... can we continue to 
integrate the changes from post http://embdev.net/topic/118781#2153401
BR Richard

von Jiri D. (jdobry)


Rate this post
useful
not useful
@ Richard G.:
I review this changes, and it is not possible use as is. It contain many 
other changes that only core. It is not encapsulated into ifdef. And I 
has not time to rewrite it.
Please send me it as "patch", or I must say sorry for this moment. I 
have some urgent concern to solve.

Jiri

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, what you mean with patch ? example please

von Jiri D. (jdobry)


Rate this post
useful
not useful

von Chris (Guest)


Rate this post
useful
not useful
Hi!

I flashed 7 rondostates with the firmware of 29.8.2011. It seems to me 
that the vent does not open, even if the room is too cold.
Example: Temperature is 18,7, wantet temperature is 20, Vent is about 
55-60%. (max vent position 96, min position 30).

Maybe I have to set min position to a higher value, because the vent 
closes at about 45%?

Chris

von Holger T. (holgert)


Rate this post
useful
not useful
Hi,
I plan to buy RFM12(x) modules to use with HR20E. What are the correct 
types to use?

Currently I prefer:
RFM12 for MASTER (because it is specified for 5V)
RFM12B for all (Rondostat-) slaves  (because it is specified for 3,3V).

What frequency should be used: 433MHz vs. 868MHz?

What types are supported by current existing SW? (I didn't find any 
switch in source code to choose B-Type or 433/868MHz)

Thank you for some useful suggestions.
-Holger

von Frank (Guest)


Attached files:

Rate this post
useful
not useful
I want use some HR20 as central control. Temperatures are measured 
externally. To to this i have extended the firmware:

1. Improved input operation in com.c

2. Serial Bus mode Ixx enables the communication with ID=xx all other 
devices are silent.

3. Override measured themperature via Oxxxx

4. Debug prints free RAM

With 2. i have an problem. Variable 0x27 holds the bus id but i cannot 
change this. 0x27 is allays set to 0xff

By the way:

5. i can communicate only with 1200 baud when i set COM_BAUD_RATE to 
1140 on higher speed i receive no correct characters.

6. the hr20 prints 22.6°C while an DS1820 messures 24.87°C

7. i have changed the boot loader to fastboot. With lboot i can flash 
with 115200 baud

von jdobry (Guest)


Rate this post
useful
not useful
@Holger T.: I use 868MHz modules. RFM12B is improved version of RFM12. I 
recomend new.

@Frank: Thanks for patch I will try it later.
add 5) see to http://atmel.com/dyn/resources/prod_documents/doc2555.pdf

add 6) HR20 use only cheap thermistor. But you can calibrate it in 
EEPROM

add 7) I don't use bootloader. Reason is some temporary problems with 
flash space and in this case, every byte is needed.

von Richard G. (gggggg)


Attached files:

Rate this post
useful
not useful
Hi Jiri, as wanted here is the Tortoise SVN patch...
Only those chenges are relevant: 
http://embdev.net/topic/118781?page=4#2153401
Explanations start here http://embdev.net/topic/118781?page=4#2140184

von Frank (Guest)


Attached files:

Rate this post
useful
not useful
I have written an r/c clock calibration code. I uses no timers other 
than rtc and no interrupts. I thin this code is good enough to call it 
periodically to avoid communication problems while voltage or 
temperature is changing.

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri, you remember I also had calibration errors last year.... again 
this year on different valve..
It is the error from the else part (my ident CTL_error_jr =  2)
1
                    if (MOTOR_ManuCalibration==0) {
2
                        if (a >= MOTOR_MIN_IMPULSES) {
3
                            MOTOR_ManuCalibration = a;
4
                            eeprom_config_save((uint16_t)(&config.MOTOR_ManuCalibration_L)-(uint16_t)(&config));
5
                            eeprom_config_save((uint16_t)(&config.MOTOR_ManuCalibration_H)-(uint16_t)(&config));
6
                            MOTOR_calibration_step = 0;
7
                        } else {
8
                            MOTOR_calibration_step = -1;     // calibration error
9
                            CTL_error |=  CTL_ERR_MOTOR;
10
                      CTL_error_jr =  2; //jr CTL_ERR_MOTOR;

MOTOR_PosMax 47, MOTOR_PosAct 47, MOTOR_PosOvershoot 2,
MOTOR_counter 5E6, motor_diag 779

How it happens:
1 I pressed a button and got E2 (valve not mounted, maybe I pressed to 
hard ;-)
2 I took valve off
3 I set the heater valve head manually near full open
4 put valve back on
5 valve starts adapting and stops with the error on full open position

I took it off again and repeated from 3. Same error again ...
Then I took battery out and repeated from 3. No more error !

von Chris (Guest)


Rate this post
useful
not useful
Hi Jiri,

I too experienced a E3 error and could not find any reason for it, but 
it could be because I used empty batteries.

With current version, I have 2 main problems:

1: The window open function still triggers randomly, for example if the 
central heating goes out for a few minutes and there is a slight drop in 
temperature. I tried different eeprom settings to disable the window 
open detection, but it still triggers.

2: With default settings, valve is always around 50%. Our water 
temperature is only high enough to reach wanted temperatures, but only 
if vents are at about 90%. So I increased the value for valve-center.

Problem is that valve is opend or closed with a too flat curve. For 
example, when wanted temperature is 20 and real temperature is 21, valve 
only closes a little bit, which is not enough.
I think I have to change impact of P-Part of the controller?

Chris

von Bernard K. (bernard_k)


Rate this post
useful
not useful
Hi all,

I've been reading this, and the other German thread (through google 
translate), along with the documents referenced in those, but still have 
some questions.

I currently have one HR20 and one HomExpert HR20Style. As soon as I get 
everything working I will purchase 7 more HR20Style (since they're 
cheaper than the original HR20.)

My goal is to power and control the thermostats over wiring already 
present for this purpose.
What I need to do is to set the desired temperature, and read the actual 
temperature. Reading the valve state would be a plus.

I now have the HR20 hooked up (it's SW 204), and can read the 
information it sends me (fe.: "K: 0b1 [0x0D][0x0A]>")
I cannot successfully send it any commands, I always get the message 
"Error in command[0x0D][0x0A]>"
After a while any commands I send it are ignored. (I assume the device 
has gone to sleep.) I have not found a way to wake it up.
Apparently all this is because the information I'm using concerns the 
protocol of an earlier hardware version (with a NEC chip instead of the 
Atmel AVR mine has?)
I have not found a protocol specification for the SW 204 specifically.

Is it possible to control the SW 204 in the same way as the earlier 
edition? If so, could someone point me to the correct protocol 
specification?

If not, then I assume I will need to flash the HR20 with OpenHR20? I 
have a ICSP programmer, but as I understand it I cannot use this unless 
I actually open up the HR20 and solder some extra wires to it?
So I've ordered a cheap AVR JTAG ICE from ebay (I figure I'll be able to 
use it later for other purposes anyway, even if I don't need it after 
all.)

If I'm correct so far, these would be the steps required to flash the 
HR20?
* I will not be able to connect the JTAG connector directly to the HR20 
and will need to make some wires to connect the right pins to the JTAG 
connector.
* I will then use avrdude (I do not have any Windows) to upload the file 
hr20.bin to the HR20 using the AVR JTAG ICE.
* Afterwards, I can use the OpenHR20 protocol to accomplish my goal.

I've checked out the svn repo, and have also downloaded the v1.0 
zipfile.
I see no .bin files inside the svn repo.
Is the zipfile's original_sww/hr20.bin the file I need, or would you 
recommend (considering my goal) to compile one from the latest svn 
source instead?
If I need to compile a bin file, could you tell me how to do this? My C 
knowledge is very limited, so the correct avr-gcc (if that is the 
correct application?) command line would be very helpful.

All the thanks,
Bernard Kerckenaere

von Jiri Dobry (Guest)


Rate this post
useful
not useful
Bernard K:
- serial protocol for original SW 204 is unknown.
- I don't known if HR20 style contain same HW as HR20. Please check it 
ane tell us results.
- You are right ICSP can't be used without open valve and soldering.
- connector on HR20 have't same layout like AVR JTAG, you will need 
special cable.
- I am not using Windows too. You need "avr-gcc" package. On actual 
source directory simple start "make". I recommend do it in "rfmsrc" 
directory and result hex files will be on "bin"
- Here is TESTED avrdude commands. You will probably need both in same 
order. Without first is impossible rewrite EEPROM.
1
avrdude -p m169 -c jtag1 -P /dev/ttyUSB0 -U hfuse:w:0x19:m
2
avrdude -p m169 -c jtag1 -P /dev/ttyUSB0 -e -U flash:w:hr20.hex -U eeprom:w:hr20.eep -U hfuse:w:0x11:m

von Jiri Dobry (Guest)


Rate this post
useful
not useful
update: for compile under linux you need "gcc-avr" and "avr-libc"

von Frank (Guest)


Attached files:

Rate this post
useful
not useful
@Jiri, @Bernard
I have flashd without soldering. All ISP pins are on the connector and 
under the tree keys. The display can be easy removed from battery side.

With fastboot 
http://www.mikrocontroller.net/articles/AVR_Bootloader_FastBoot_von_Peter_Dannegger 
the new firmware can be flashd via serial cable.

This is my modified Makefile:
1
--- Makefile.orig    2011-09-29 10:50:21.000000000 +0200
2
+++ Makefile    2011-09-29 11:02:07.015224003 +0200
3
@@ -37,7 +37,7 @@
4
 # MCU = attiny85
5
 # MCU = atmega2560
6
 # MCU = atmega1281
7
-MCU = atmega8
8
+MCU = atmega169p
9
 
10
 # Name of the Atmel defs file for the actual MCU.
11
 #
12
@@ -50,16 +50,16 @@
13
 # files" and unzip it in the same directory as this Makefile.
14
 #
15
 # Examples (select one of them or add your own):
16
-# ATMEL_INC = m168def.inc
17
+ATMEL_INC = m169def.inc
18
 # ATMEL_INC=m64def.inc
19
 # ATMEL_INC=tn85def.inc
20
 # ATMEL_INC = m2560def.inc
21
 # ATMEL_INC = m1281def.inc
22
-ATMEL_INC = m8def.inc
23
+#ATMEL_INC = m8def.inc
24
 
25
 # Processor frequency.  The value is not critical:
26
 #F_CPU = 14745600
27
-F_CPU = 8000000
28
+F_CPU = 4000000
29
 
30
 #     AVR Studio 4.10 requires dwarf-2.
31
 #     gdb runs better with stabs
32
@@ -68,11 +68,11 @@
33
 
34
 # Define the Tx and Rx lines here.  Set both groups to the same for
35
 # one wire mode:
36
-STX_PORT = PORTD
37
-STX = PD1
38
+STX_PORT = PORTE
39
+STX = PE1
40
 
41
-SRX_PORT = PORTD
42
-SRX = PD0
43
+SRX_PORT = PORTE
44
+SRX = PE0
45
 
46
 ####### End user presets ######################

This is my avrdude call. You need the EEPROM image from OpenHR20
1
sudo avrdude -c usbtiny -p m169 -u \
2
        -U flash:w:bootload.hex \
3
        -U eeprom:w:../OpenHR20/openhr20/trunk/source/hr20.eep \
4
        -U efuse:w:0xfd:m \
5
        -U hfuse:w:0x94:m \
6
        -U lfuse:w:0xe2:m

von Jiri Dobry (Guest)


Rate this post
useful
not useful
I am sorry, in avrdude commands I write invalid hfuse. Here is correct:
1
avrdude -p m169 -c jtag1 -P /dev/ttyUSB0 -U hfuse:w:0x99:m
2
avrdude -p m169 -c jtag1 -P /dev/ttyUSB0 -e -U flash:w:hr20.hex -U eeprom:w:hr20.eep -U hfuse:w:0x91:m

von Bernard K. (bernard_k)


Rate this post
useful
not useful
Thank you very much for all the information, I really appreciate it!

I'll wait for my JTAG programmer to arrive (it's on its way, and looks 
to be a bit easier to use than ISP), and will then try and verify 
whether I can flash and get the sought after results on both the HR20 
and the HR20Style.

Again thank you!

von Jiri Dobry (Guest)


Rate this post
useful
not useful
Richard G: your patch file "richard363_111008.patch" is not possible 
apply to fresh 363 revision. You probably made same mistake.

von Richard G. (gggggg)


Rate this post
useful
not useful
Jiri: I thought it might be a good idea to just include the files with 
major changes. Otherwise you will also get beautifiing stuff ... do you 
want them all ?

von rps (Guest)


Rate this post
useful
not useful
Hi!

Did anybody consider adding 1-wire connectivity yet?
(Axel_5 mentioned something in other threads but no details.)

This could use the one free pin in the connector (PE2 I think). No need 
for Hardware adaptions.

The device could mimic multiple "standard" 1-wire devices:
- a temperature sensor (RTC value)
- ADC (valve target position)
- EEPROM (non-volatile config)
- RAM (current state)
perhaps even:
- switch/PIO (for buttons) but this would possibly be missed when 
polling is intentionally slow.

User interface would need the possibility to configure the address.

I'm thinking of semi-autonomous operation - current target mode and 
timetable are uploaded regularly, temperature values are centrally 
logged.

Full "slave mode", just using the temperature sensor, the valve actor 
and the wheel and buttons for user requests and doing the rest centrally 
would also be possible.

I plan to implement this, but would like to hear your thoughts.

von Bruce A. (bruce_a)


Rate this post
useful
not useful
I got the first HR20-E flashed with JTAG last night. I'm very impressed. 
So thanks. Now, my question, assuming this is the right forum for 
this...

I also got an HR-25 
(http://www.homexpertbyhoneywell.com/en-DE/Products/rondostat/Pages/HR-25.aspx) 
which has a very, very similar PCB to the HR-20. It has a MEGA329P on 
board and a fancier LCD and only a couple of extra tracks/vias that I 
can spot. I'm tempted to get more of these instead for the nicer LCD and 
bigger code space.

Before I go reinventing wheels, has the OpenHR20 code been ported to 
this, the LCD mapped out etc.? i.e. has anyone done work already on 
supporting the HR25?

von Axel L. (axel_5)


Rate this post
useful
not useful
>Did anybody consider adding 1-wire connectivity yet?

I can upload my code tonight.

However I have forked this a long time ago, so maybe it is quite 
difficult to merge this in the current branch.

Basically the temperature can be read as a simple 1-wire temperature 
sensor, target temperature can be set. The value of the valve can also 
be read.

However power consumption is quite high as I have removed all sleep 
modes as the device is always powered through the cable. Also the 
timetable is removed as this is now done by the central controller.

Best regards
Axel

von Jiri D. (jdobry)


Rate this post
useful
not useful
@Axel Laufenberg:
If you want store your code into repository please contact me on 
jdobry-at-centrum-dot-cz and send me your account name from sourceforge.
Is it based on trunk(I will not make improvements) or rfmsrc 
(recomended)?
If it is encapsulated to "ifdef" preprocessor you can add this into 
current code. Otherwise please create new branch in repository.

von Axel L. (axel_5)


Attached files:

Rate this post
useful
not useful
Sorry, I do not have time right now to add to the repository, I just 
spent some time to translate most of the stuff into English. And I 
recognized that I used a version from 2008, so I guess this does not 
have too much in common with the current version.

Actually only the attached files are affected. The main.c only gets the 
additional function to assign the values received and transmitted 
from/to the onewire interface and gets the sleep mode disabled.

motor.c is changed because the external interrupt is used. This now has 
to handle also the 1-wire edge handling. The file onewire.c handles the 
timing for the onewire. I just recognised that the ISR is in the code 
twice, once within the motor.c and once in the onewire.c. Actually it is 
only used in motor.c as otherwise the interrupt routine may be too slow.

Actually you should be aware that the AVR needs to be clocked at 8 Mhz, 
otherwise it is too slow to handle the onewire timing.

I tried to document as good as possible, so it should be no problem to 
add this to the code.

If I find the time I can try to make this all a bit nicer and merge it 
with the repository, but ....

So I hope this is in any case helpful to somebody, if you have questions 
please feel free to ask.

Axel

von Rupert S. (rps)


Rate this post
useful
not useful
@Axel:

Wow, thanks a lot - mostly what I hoped for. It's a pity that it will 
need to run on 8MHz.
The code looks good and well documented too (and I have no problem with 
the german parts ;-) ).

@Axel&Jiri:
When I have this running (which still might take me a few weeks), I'll 
try to integrate it with the current version and into the repository. 
Maybe I can even invest some of the effort saved into thinking a bit 
more about the 1-wire-bootloader :-).

Rupert

von Bruce A. (bruce_a)


Attached files:

Rate this post
useful
not useful
I have got the LCD working on the HR25. It seems to work fine. I'll have 
to wait until the RFM12s arrive before testing further. See 
https://sites.google.com/site/slangey/misc/honeywell-hr25 for some more 
details including pictures of the board.

I've done the changes against rfmsrc and it touches the Makefile, 
lcd.c/.h and rs232_485.c/.h. I would appreciate if someone could please 
review and give comments before (hopefully) getting this in to svn?

Bruce.

von Jiri D. (jdobry)


Rate this post
useful
not useful
Bruce_a:
I made fast review and looks OK. Committed into revision 364.
PS: I made only small fix (compilation need remove one space in 
rfmsrc/OpenHR20/Makefile) and modify rfmsrc/Makefile to create new 
target platform files.
It looks that it can support hardware window detection and RFM without 
any additional changes. But I am not create target files for this 
because I can't test it.

von Knut S. (kschwi)


Rate this post
useful
not useful
Is there any technical difference between HR20 and HR25 than CPU and 
display? There is at least little space left in the 169 flash so it 
might make sense to replace the CPU and take the HR25 SW-version.
Cheers,
Knut

von Bruce A. (bruce_a)


Rate this post
useful
not useful
Hi Knut,

It would appear just to be a CPU/LCD difference. Amtel's migration docs 
suggest not much interesting has changed. The code would need just one 
more target to specify the new cpu correctly. Be aware that the cheap 
JTAG programmer I got off ebay doesn't program the 329 :( (see the link 
in previous post). So I'm thinking RFM12b & serial bootloader... and/or 
replacing the JTAG pins on the side with ISP ones.

von StuartP (Guest)


Rate this post
useful
not useful
Hi All,

I've been watching this thread for a while now, and have taken the 
plunge and purchased an HR20.

Could someone advise what is the best lowcost JTAG programmer to get 
started with for the HR20.

Cheers

Stuart

von Bernard Kerckenaere (Guest)


Rate this post
useful
not useful
I ordered this one:

New AVR USB Emulator debugger programmer JTAG ICE+Protecter for US 
$10,90

http://www.benl.ebay.be/itm/200667489423?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649

von StuartP (Guest)


Rate this post
useful
not useful
Thanks for the info.

Is anyone using linux to do development work & programming ? This would 
be my preferred environment.

von Bernard Kerckenaere (Guest)


Rate this post
useful
not useful
I do.

See Jiri Dobry's posts of 2011-11-01 for some information on how to go 
about creating and flashing the necessary file.

von StuartP (Guest)


Rate this post
useful
not useful
Bernard, thanks. Out of interest what sort of USB device does your 
programmer appear as, is it FTDI based ?

von Bernard Kerckenaere (Guest)


Rate this post
useful
not useful
I haven't received mine yet, but according to the documentation it's 
CP2102-based, not FT232.

That said, CP2102 support is part of the usb-serial driver nowadays, so 
I don't foresee any problems there.

von Bernard Kerckenaere (Guest)


Rate this post
useful
not useful
Jiri Dobry:

I keep getting these messages:

avrdude: Device signature = 0xffffff
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.


And when I try it with -F, I get this after setting the fuse:

avrdude: jtagmkI_initialize(): warning: OCDEN fuse not programmed, 
single-byte EEPROM updates not possible
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 
0.04s

avrdude: Device signature = 0xffffff
avrdude: Yikes!  Invalid device signature.
avrdude: Expected signature for ATMEGA169 is 1E 94 05
avrdude: reading input file "0x99"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 
0.01s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0x99:
avrdude: load data hfuse data from input file 0x99:
avrdude: input file 0x99 contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading |                                                    | 0% 
0.00savrdude: jtagmkI_read_byte(): timeout/error communicating with 
programmer (resp )


and this after flashing:

avrdude: jtagmkI_initialize(): warning: OCDEN fuse not programmed, 
single-byte EEPROM updates not possible
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 
0.04s

avrdude: Device signature = 0xffffff
avrdude: Yikes!  Invalid device signature.
avrdude: Expected signature for ATMEGA169 is 1E 94 05
avrdude: erasing chip
avrdude: jtagmkI_initialize(): warning: OCDEN fuse not programmed, 
single-byte EEPROM updates not possible
avrdude: reading input file "hr20.hex"
avrdude: input file hr20.hex auto detected as Intel Hex
avrdude: writing flash (12842 bytes):

Writing | ################################################## | 100% 
2.93s

avrdude: 12842 bytes of flash written
avrdude: verifying flash memory against hr20.hex:
avrdude: load data flash data from input file hr20.hex:
avrdude: input file hr20.hex auto detected as Intel Hex
avrdude: input file hr20.hex contains 12842 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 
3.13s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x14 != 0xff
avrdude: verification error; content mismatch

avrdude: safemode: Fuses OK

avrdude done.  Thank you.


I've connected the device as follows:
With the debug port on the HR20, seeing it with the controls on top and 
the valve connector on the left:
 bat [rx] tdo  tms  rst
 gnd tdi  [tx] tck  [pe2]
I've connected to the jtag device (as seen from the end of the cable 
with the thick part on bottom):
 gnd  -   rst  bat  gnd
 tdi  -   tms  tdo  tck
I've made sure that the correct wires from the hr20 are going to the 
jtag device (using the above for the hr20, and the silkscreen on the 
jtag device), and I've checked the cable I made from one end to the 
other for both shorts and breaks, and everything seems fine to me.

Have I got some of the connections wrong?



StuartP, this is how my ubuntu 11.10 sees the device:

[161812.004460] usb 5-2: new full speed USB device number 2 using 
uhci_hcd
[161812.643212] usbcore: registered new interface driver usbserial
[161812.643229] USB Serial support registered for generic
[161812.643276] usbcore: registered new interface driver 
usbserial_generic
[161812.643279] usbserial: USB Serial Driver core
[161812.663934] USB Serial support registered for cp210x
[161812.663975] cp210x 5-2:1.0: cp210x converter detected
[161812.772084] usb 5-2: reset full speed USB device number 2 using 
uhci_hcd
[161812.977264] usb 5-2: cp210x converter now attached to ttyUSB0
[161812.977284] usbcore: registered new interface driver cp210x
[161812.977286] cp210x: v0.09:Silicon Labs CP210x RS232 serial adaptor 
driver

von Jiri D. (jdobry)


Rate this post
useful
not useful
>> avrdude: Device signature = 0xffffff
This means that you have not connection or JTAG programmer is broken, 
AVR chip broken, JTAG is disabled in AVR fuses (it can be done by SPI 
programmer)
MOST probably version is that you have some problem on wires.

Your pinuot in text looks fine. You can compare it 
openhr20.svn.sourceforge.net/viewvc/openhr20/trunk/doc/steckerbelegung/s 
teckerbelegung.jpg

JTAG pinout is here http://mdfly.com/images/Wireless/JTAGlayout.jpg

Are you sure that you not rotate/mirror some connector. I mean swap pin 
1-5 5 or 1-2 or rotate some pinout 180deg ?

von Marco G. (stan)


Rate this post
useful
not useful
Bernard, did you also check with TDI and TDO crossed?

von Bernard Kerckenaere (Guest)


Rate this post
useful
not useful
I just tried crossing TDI and TDO, but I'm getting the same result.

How should they be connected in fact? TDI of HR20 to TDI of JTAG 
(according to the pinout in the jpgs Jiri posted), or crossed?

I'm sure everything is correct as it should be, I've measured the cable 
through from one end, where it connects to the pins on the programmer, 
to the other, where it goes onto the pins of the HR20. The pinouts I've 
followed are the same as in the jpegs as well, and match the silkscreen 
on my programmer.
And as soon as I connect the cable to the HR20, the second light on the 
programmer goes on, where the voltage protector gets its power from the 
Batt pin on the HR20,  so if that pin is correct, the orientation should 
be correct too.

There isn't anything I need to do on the HR20 itself before I can start 
using the jtag right? I've put in batteries, and now it's blinking 2005, 
and I haven't done anything else to it since.

I'll play with it some more tomorrow morning. If you would have any 
other  tips on what I could try, I'm all ears. I'm quite new to this, so 
I don't have a lot of experience in debugging errors like these.

Thank you for all the help so far!

von Bernard Kerckenaere (Guest)


Rate this post
useful
not useful
Ah, one more thing: I've also taken off the valve part, so I could put 
batteries inside, and I haven't put that part back on.
I don't know if that makes any difference, but I figure I'd better 
mention this as well.

von Marco (Guest)


Rate this post
useful
not useful
Basically, the programmer and the target shall be a daisy chain 
regarding TDO and TDI, but it depends on the description of the 
programmer: whether it is its output for or the target's output.

I am using an AVR Dragon with AVR Studio on Win7. The batteries have to 
be inserted. When reading and programming, the Dragon resets the HR20, 
so it does not matter in which state the HR20 is...

von JanW (Guest)


Rate this post
useful
not useful
is there anywhere a discription, how to make the hex-file to programm 
the hr20? i find in the repository nothing how to do it. i want to 
programm the hr20 by SPI, i habe no jtag-programmer, i know that i have 
to sold some cables to the pcb, but its ok for me. but i need the 
hex-file

thx a lot

Jan

von JanW (Guest)


Rate this post
useful
not useful
ok, i found something in the rfmsrc/openhr20 folder. do i need any of 
these files to make the hex-file? i also found the description in 
branches/before_refactoring/doc, this can i use to make the hex-file or?

von Bernard Kerckenaere (Guest)


Rate this post
useful
not useful

von Jiri D. (jdobry)


Rate this post
useful
not useful
Compilation: it simple, just start "make" command (command line)
JTAG: right connection is TDI-TDI and TDO-TDO

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.