PDA

View Full Version : Easy way to do multiple write statements ?



Scampy
- 3rd January 2016, 19:37
Guys, need some advice as I'm currently brain dead trying to work out a solution to this issue.

I'm working on a project that has multiple array variables to store times and PWM value (word). Three are 16 variables for on hours, 16 variables for on minutes, 16 variables for off hours, 16 for off minutes and 16 for the PWM value

Rather than have to do each line for the 80 WRITE statements, eg (not actual code, just to give the gist of things)


write address$, setHR(1),setMN(1),offHR(1),offMN(1),pwm(1)lowbyte, pwm(1)highbyte
write address$+1, setHR(2),setMN(2),offHR(2),offMN(2),pwm(2)lowbyte, pwm(2)highbyte
write address$ +2, setHR(3),setMN(3),offHR(3),offMN(3),pwm(3)lowbyte, pwm(3)highbyte
etc


is there a way of doing this with a single statement ?

I did try a for / next loop, placing the counter variable in the brackets



address =$50
for counterd = 1 to 16
write address,lightsetHR(counterD),lightsetMN(counterD), lightoffHR(counterD),lightoffMN(counterD),fadeset( counterD)
next counterD


which works for the initial run when Counter =1, but then overwrites the address on the subsequent loops when counter = 2 to 15. I assume I need to add a value to the address or something, which I tried by adding a line which added 16 to the value, but that didn't work..

Ideally what I'm after is the first time the device is run it reads a set of default timings and pwm values until these are changed by using menu options or a PC application, which then writes the new values to the PICs memory, and sets a flag. The next time the unit powers up, it checks to see if the flag has been set and if so loads the saved valued from memory.

Any ideas

Charlie
- 3rd January 2016, 20:05
address =$50
for counterd = 0 to 15
write (address +counterD),lightsetHR(counterD),lightsetMN(counter D),lightoffHR(counterD),lightoffMN(counterD),fades et(counterD)
next counterD

Ioannis
- 3rd January 2016, 20:29
Although not specified directly, i'd first would make the math and then place the result in the write command:

temp1=addres+counterD

write temp1... etc

I2Cwrite and I2Cread commands work only this way.

Ioannis

Scampy
- 3rd January 2016, 21:08
Although not specified directly, i'd first would make the math and then place the result in the write command:

temp1=addres+counterD

write temp1... etc

I2Cwrite and I2Cread commands work only this way.

Ioannis

So the normal WRITE command won't work in this way ?

Jerson
- 4th January 2016, 00:57
Assuming that each of the hours and minutes are bytes and PWM value is a word, the write command will fill up 6 bytes on each pass. So, the code would become


address =$50
for counterd = 0 to 15
write (address + (counterD*6)),lightsetHR(counterD),lightsetMN(coun terD),lighto ffHR(counterD),lightoffMN(counterD),fadeset(counte rD)
next counterD


OR you could also do this


address =$50
for counterd = 0 to 15
write (address),lightsetHR(counterD),lightsetMN(counterD ),lighto ffHR(counterD),lightoffMN(counterD),fadeset(counte rD)
address = address+6 ' account for the data already filled into the storage
next counterD

Amoque
- 5th January 2016, 13:08
You spoke in your original post of an "easier way", while this is not exactly what you asked, I find it easier and so offer...

Keeping track of hours and minutes separately is unnecessary. For me, over and again, I have determined that a word value representing the minutes since midnight (a value of 0 to 1440) is clearer and easier to manipulate. Switching to hours and minutes is as easy as /60 for hours and MOD 60 for minutes. All calculations loose the clumsiness of handling hours and minutes separately and determining if dates change when subtracting or adding periods is less complicated.

It doesn't save any actual eeprom space, but it could reduce the typing by changing "lightsetHR(counterD),lightsetMN(counterD)," to SetTime(counterD) and "lightoffHR(counterD),lightoffMN(counterD)," to OnOffTime(counterD)

... just a thought.

Scampy
- 5th January 2016, 18:30
You spoke in your original post of an "easier way", while this is not exactly what you asked, I find it easier and so offer...

Keeping track of hours and minutes separately is unnecessary. For me, over and again, I have determined that a word value representing the minutes since midnight (a value of 0 to 1440) is clearer and easier to manipulate.
... just a thought.

I agree and that's the way I do the matching of the if then statements. The code reads the RTC, and the end result is placed in two variables, TimeH and TimeM. Then the TimeH is multiplied by 60 and added to TimeM and placed in a variable Counter1. I then have a similar statement CH1_on_Time = (lightsetHR1*60)+lightsetMN1 to convert the values in the above statement which are then placed in a variable, and then it's a simple matter to do the actions required depending on if the two variables match or one is < or > than other.

Oh and just to update this thread, and for reference for anyone in the future who may stumble on this thread...



address =$50
for counterd = 0 to 15
read (address),lightsetHR(counterD),lightsetMN(counterD ),lightoffHR(counterD),lightoffMN(counterD),fadese t.lowbyte(counterD),fadeset.highbyte(counterD)
address = address+6 ' account for the data already filled into the storage
next counterD


With the the matching WRITE command, works a treat :) - thanks Jerson ;-)

Scampy
- 7th March 2016, 21:45
Assuming that each of the hours and minutes are bytes and PWM value is a word, the write command will fill up 6 bytes on each pass. So, the code would become


address =$50
for counterd = 0 to 15
write (address + (counterD*6)),lightsetHR(counterD),lightsetMN(coun terD),lighto ffHR(counterD),lightoffMN(counterD),fadeset(counte rD)
next counterD


OR you could also do this


address =$50
for counterd = 0 to 15
write (address),lightsetHR(counterD),lightsetMN(counterD ),lighto ffHR(counterD),lightoffMN(counterD),fadeset(counte rD)
address = address+6 ' account for the data already filled into the storage
next counterD


Guys, I need a little help in a similar vein.

I'm working on a slightly different program using similar variables only this time I save 48 word variables, which results in 96 lines of code for both WRITE and READ statements. The word variables are
CH1_Max, CH1_on_Time, CH1_off_Time, so I have



read 40,CH1_on_Time.lowbyte
read 41,CH1_on_Time.highbyte
read 42,CH2_on_Time.lowbyte
read 43,Ch2_on_Time.highbyte


Rather than have 96 lines of code is there a simple way to do this with a FOR / NEXT loop similar to above

I did try




for n = 8 to 38 step 2
READ n, ch(n)_max.lowbyte
next n


for n = 9 to 39 step 2
READ n, ch(n)_max.highbyte
next n


But this just threw up errors when I tried compiling (I'm using PBP 2.60c)

Any suggestions ?

richard
- 7th March 2016, 22:36
the "EXT" modifier make this a breeze , see if you can follow this example





amps Var Word ext ;chg mA
volts Var Word ext ;chg V
kp var word ext
kd var word ext
ki var word ext
f_0 var byte ext
f_1 var byte ext
f_2 var byte ext
f_3 var byte ext
setpoint var word ext ;out volts
cl var word ext ;current limit
flgs VAR byte ext
drive var word ext ;current pwm value
a_cal var word ext
v_cal var word ext
bat_r Var byte ext ;bits 0:3 is batt being charged , 4:7 batt connected flg
data_blk var byte[26]

asm
volts = _data_blk ;01
amps = _data_blk+2 ;23
flgs = _data_blk+4 ;4
drive = _data_blk+5 ; 56
F_0 = _data_blk+7
F_1 = _data_blk+8
F_2 = _data_blk+9
F_3 = _data_blk+10
setpoint = _data_blk+11 ;1112
bat_r = _data_blk+13
ki = _data_blk+14 ;1415
cl = _data_blk+16
kp = _data_blk+18
kd = _data_blk+20
a_cal = _data_blk+22
v_cal = _data_blk+24 ;2425

endasm

to save


for n =0 to 25
write n, [data_blk[n]]
next n


to read


for n =0 to 25
read n, [data_blk[n]]
next n


to just save vars f_0 to f_3


for n =7 to 10
write n, [data_blk[n]]
next n

or even better


for n =0 to 3
write n, [f_0[n]]
next n

Ioannis
- 8th March 2016, 07:53
Richard,

what is the difference in using EXT ant this one?



data_blk var byte [25]
f_0 var data_blk[7]


Ioannis

richard
- 8th March 2016, 08:05
ioannis


data_blk var byte [25] this reserves 25 bytes for our data

f_0 var data_blk[7] would definitely point to the correct byte but if you add or delete or rearrange or modify any vars in the array you have to go back and make sure the index is corrected , its easy to make a mistake and forget

whereas :-

using
f_0 var byte ext the assembler does all the work and we still get an index-able byte sized pointer to use