Correct Date/Time conversion

Started by lrice648, November 29, 2015, 02:10:54 PM

Previous topic - Next topic

lrice648

Hi everyone, I am working on an arduino base monitoring system and I have run into a snag when trying to correctly pull the date and time out of my classic 150.

I'm specifically running into issues getting the correct day of the month. I had the classic on my bench almost a year ago when I first started tinkering with pulling data off with the arduino and I did enough basic proof of concept to be sure I could do it and then I went ahead and expanded my solar system (at my family farm, quite a ways a way from where I actually live) so I've been simulating the device ever since (sometimes just in code, sometimes via a MODBUS simulator running on a PC).

When I went home this weekend to test it out I was pleased that everything worked, except my formatting of the date and time was not correct. I had made a couple mistakes (I thought the combo of registers 4214 and 4215 would have 4214 as the low order word and 4215 as the high order word, switched them and '16 and '17 and that fixed most of my issues) but I still have a problem with at least getting the correct month number.

I dumped out the raw data for each of the registers (in decimal obviously) and I'm trying to figure out where I went wrong. The approximate date/time was 11/27/2015 05:06 pm. I should have recorded very precicely what the classic showed for the date/time but I saved the textfile with my arduino output at 5:06 pm so it was likely a minute or so before that that I actually pulled the date. My current conversion is yielding this: 2015-0-27 17:11:27

Raw Registers:

4214:529
4215:2843
4216:2015
4217:91

The modbus datasheet (2 years old unfortunately) has the 4217 register as holding the day of the month and the month number at bits 4:0 and 11:8 respectively. 4:0 correctly yields 27. The 2nd date register is 4216, which holds the correct year value and nothing more. It could be a totally odd coincidence that while the hour is correct (17 in 24 hr time), the minute and second numbers just happen to be 11:27, the correct month and day.

I pasted below how I have hardcoded the values for testing purposes since I didn't have time to troubleshoot it further over thanksgiving. Does anyone know off hand where I am messing up? Is there a chance these register numbers are not correct and the pdf is out of date?

Thanks for any help you can offer.


uint16_t time2 = 529; //4214
uint16_t time1 = 2843; //4215
uint16_t date2 = 2015; //4216
uint16_t date1 = 91; //4217

year = (date2)& 0x0FFF;
month = (date1 >> 8) & 0x000F;
day = date1 & 0x001F;
hour = (time2)& 0x001F;
minute = (time1 >> 8) & 0x003F;
second = (time1)& 0x003F;



Westbranch

Don't quote me , but I think RESTHOME did something about time registers in the Local App section or My Midniite section when he downloaded hid data... you might send a personal message to him....
KID FW1811 560W >C&D 24V 900Ah AGM
CL150 29032 FW V.2126-NW2097-GP2133 175A E-Panel WBjr, 3Px4s 140W > 24V 900Ah AGM,
2 Cisco WRT54GL i/c DD-WRT Rtr, NetGr DS104Hub
Cotek ST1500 Inv  want a 24V  ROSIE Inverter
OmniCharge3024  Eu1/2/3000iGens
West Chilcotin 1680+W to come

dgd

I did it the long way, right and left bit shifting and casting as necessary to extract values.
For some reason I never investigated, the 'anding' with mask never worked for me and uint16_t
wasn't  :o


   // time registers at address 4213,  secs and mins, 4214 hours and weekday
   // bit pattern 4213  ..mmmmmm..ssssss and 4214  .....ddd...hhhhh
   // casting to unsigned int necessary to prevent right shifting leftmost 1 results in negative number
     ctime_secs[k] = idRegs[4] << 10;
     ctime_secs[k] =  (unsigned int)ctime_secs[k] >> 10; 
     ctime_mins[k] = idRegs[4] << 2;
     ctime_mins[k] = (unsigned int) ctime_mins[k] >> 10;
     ctime_hrs[k] = idRegs[5] << 11;
     ctime_hrs[k] = (unsigned int) ctime_hrs[k] >> 11;   
     ctime_weekday[k] = idRegs[5] << 5;
     ctime_weekday[k] = (unsigned int) ctime_weekday[k] >> 13;
     ctime_day[k] = idRegs[6] << 11;
     ctime_day[k] = (unsigned int)ctime_day[k] >> 11;
     ctime_mth[k] = idRegs[6] << 4;
     ctime_mth[k] = (unsigned int) ctime_mth[k] >> 12;


dgd
Classic 250, 150,  20 140w, 6 250w PVs, 2Kw turbine, MN ac Clipper, Epanel/MNdc, Trace SW3024E (1997), Century 1050Ah 24V FLA (1999). Arduino power monitoring and web server.  Off grid since 4/2000
West Auckland, New Zealand

lrice648

Cool, thanks for the help guys. Dgd, are you even reading 4216 or 4217 as part of that snippet of code? I'll have to dig through it in detail after I finish dinner, I'll report back for posterity sake :)

dgd

#4
Sorry forgot to include the line where the modbus lib function reads the actual registers.
My code uses the SimpleModbusMaster library.

In setup()

modbus_construct(packet4, 10, READ_HOLDING_REGISTERS, 4209, 9, idRegs);


here nine registers starting at address 4209 are read into the integer array idRegs when the
modbus_update function is called - usually in loop()

You can view the complete sketch (web server for Classic)  in the Arduino section of this forum

dgd
Classic 250, 150,  20 140w, 6 250w PVs, 2Kw turbine, MN ac Clipper, Epanel/MNdc, Trace SW3024E (1997), Century 1050Ah 24V FLA (1999). Arduino power monitoring and web server.  Off grid since 4/2000
West Auckland, New Zealand

dgd

Also I assume you are actually reading from the register address and not the register number?

So register 4216 is actually at address 4215

dgd
Classic 250, 150,  20 140w, 6 250w PVs, 2Kw turbine, MN ac Clipper, Epanel/MNdc, Trace SW3024E (1997), Century 1050Ah 24V FLA (1999). Arduino power monitoring and web server.  Off grid since 4/2000
West Auckland, New Zealand

lrice648

Oh wow, I am a dope, that was exactly my problem. Its funny because I haven't had a real device around to test with that even though I knew that at one point I totally forgot. I did my initial testing with a modbus master/slave tool and when I hooked up to the classic I was confused at first, then I figured it out and read the line in the modbus doc specifically laying it out. I forgot to actually include that in my arduino code though.

Thanks for the help, I was hoping I was making some basic mistake!

For posterity in case anyone comes across this and isn't sure what dgd meant, on page 2 of the classic register map it says:

QuoteNote on addressesvs.registers: The modbus specification adds one (1) to the “address” sent to the unit in the packet command to access a “register”. This is
so that modbus registers start at 1 rather than 0. The main Classic address map starts at register 4101 but the packet itself
sends out address 4100.