Setting individual array element variables (V3.5.0b1)
-
@dc42 Is that something that simply got overlooked or is there more complexity to it and we should not expect this any time soon?
-
@Diamondback I overlooked it. I've added a note to look at it for beta2.
-
@dc42 Awesome, can't wait. I'm already making great use of the new array functionality.
-
@dc42 Futher questions on arrays on 3.5...
- Is it possible to create empty arrays?
- Can we create arrays with holes?
- Any chance to also get dictionaries/some sort of map in the future?
-
@Diamondback said in Setting individual array element variables (V3.5.0b1):
@dc42 Futher questions on arrays on 3.5...
- Is it possible to create empty arrays?
- Can we create arrays with holes?
It can't be "empty", but you can set null values
global myArray= {null}
set global.myArray = {null,1,null,4,}
-
@dc42 any info on creating arrays with a given size without specifying each element right away?
As I understand it, currently the maximum array length is limited to whatever the maximum gcode command length is? Ie we can't just create an array of length 300 since we literally can't declare it in any legal way?
How about a syntax that allows us to create arrays without specifying each element? -
@Diamondback
I've been pondering this as well.
In Delphi/Pascal, dynamically creating arrays at runtime (or even just setting the length) is easy and commonplace.
I know bugger all about C/C++, but my research seems to indicate that at least some versions don't allow that.
Another option might be if we were able to pass a dynamically created string (doesn't work at present), but given the echo command uses an array of strings it may require less additional memory than adding whatever C++ libraries (or functions) are required for dynamic arrays.
Creating a string in memory should avoid the Gcode length limit. -
@OwenD oh, dynamically sized arrays would of course be even better but that might indeed have some serious memory management issues.
What would help already is if we were simply given a syntax that does not require each element to be explicitly defined.
So rather than doingvar myArray = {0,0,0,0,0}
we'd have something likevar myArray = {[5,0]}
where it says "Create an array of size 5 filled with 0s" or something like that. With 5 elements the current approach is not too much trouble, but imagine 300...
The closer the syntax to common programming languages the better, but I understand there's some issues with it being gcode and all. -
@Diamondback if/when I implement allowing changes to the values of individual array elements, I'll most likely also implement a function to create an array with a specified number of elements all initialised to the same specified value.
-
@dc42 Perfect
-
@Diamondback I've put a 6HC build that supports setting individual array elements at https://www.dropbox.com/sh/5vxz29a7400gwcy/AAAPexxpGsP0LMo0jEFOOCqVa?dl=0.
-
@dc42 Awesome, currently not at my printer, will be back on Sunday to test this
-
@Diamondback and here's a simple test program to print out prime numbers.
var limit=100 var sieve=vector(var.limit,true) var next=2 while var.next < var.limit if var.sieve[var.next] echo var.next," is prime" var multiple = var.next*2 while var.multiple < var.limit set var.sieve[var.multiple]=false set var.multiple = var.multiple+var.next set var.next=var.next+1
It would be nicer to print the prime numbers on the bed instead of echoing them - it just needs some GCode macros written to print out individual digits.
-
@dc42
I've compiled for Duet2 and this seems to be working perfectly.
I can provoke out of memory, but only with more (and bigger) arrays than I can think of a reason for having.
Thanks so much for the great work! -
@OwenD said in Setting individual array element variables (V3.5.0b1):
I've compiled for Duet2 and this seems to be working perfectly.
Need to qualify that slightly.
Arrays work perfectly, but I get a reset as soon as actual print move starts (maybe 50mm of movement before reset).
(i.e. After start.g, leveling, heating etc. have completed)
Posting for information only in case it's useful.
I'm sure it's something that would have been corrected before the b2 release, so I'll revert to the last released binary wait for b2.M122 === Diagnostics === RepRapFirmware for Duet 2 WiFi/Ethernet version 3.5beta1+ (2023-01-29 17:00:21) running on Duet WiFi 1.02 or later Board ID: 08DGM-917NK-F2MS4-7J1DA-3S86T-TZTWD Used output buffers: 9 of 26 (20 max) === RTOS === Static ram: 22192 Dynamic ram: 79424 of which 0 recycled Never used RAM 8352, free system stack 184 words Tasks: NETWORK(notifyWait,11.8%,233) ACCEL(notifyWait,0.0%,348) HEAT(notifyWait,0.1%,326) Move(notifyWait,0.0%,362) MAIN(running,87.5%,406) IDLE(ready,0.7%,30), total 100.0% Owned mutexes: WiFi(NETWORK) === Platform === Last reset 00:02:18 ago, cause: software Last software reset at 2023-01-29 18:08, reason: AssertionFailed, Gcodes spinning, available RAM 6800, slot 0 Software reset code 0x4123 HFSR 0x00000000 CFSR 0x00000000 ICSR 0x00417827 BFAR 0xe000ed38 SP 0x2001fe7c Task MAIN Freestk 31443 ok Stack: 0000019f 0047c79c 0045dc7d 00000002 0045ed89 400e1200 2000327c 200034cc 200012d4 20011348 200043d0 00000000 dffee1b2 20011e47 dffee1ba 00000001 0045bb13 00000000 2001fee8 20011958 00000001 20004884 004316e9 00000000 20011d68 20011e4f 00431dcf Error status: 0x00 Aux0 errors 0,0,0 Step timer max interval 0 MCU temperature: min 32.3, current 32.8, max 33.5 Supply voltage: min 1.1, current 24.4, max 24.6, under voltage events: 1, over voltage events: 0, power good: yes Heap OK, handles allocated/used 99/15, heap memory allocated/used/recyclable 2048/520/252, gc cycles 0 Events: 0 queued, 0 completed Driver 0: standstill, SG min n/a Driver 1: standstill, SG min n/a Driver 2: standstill, SG min n/a Driver 3: standstill, SG min n/a Driver 4: standstill, SG min n/a Driver 5: Driver 6: Driver 7: Driver 8: Driver 9: Driver 10: Driver 11: Date/time: 2023-01-29 18:10:54 Cache data hit count 4294967295 Slowest loop: 12.70ms; fastest: 0.19ms I2C nak errors 0, send timeouts 0, receive timeouts 0, finishTimeouts 0, resets 0 === Storage === Free file entries: 10 SD card 0 detected, interface speed: 20.0MBytes/sec SD card longest read time 1.6ms, write time 0.0ms, max retries 0 === Move === DMs created 83, segments created 0, maxWait 0ms, bed compensation in use: none, comp offset 0.000 no step interrupt scheduled === DDARing 0 === Scheduled moves 0, completed 0, hiccups 0, stepErrors 0, LaErrors 0, Underruns [0, 0, 0], CDDA state -1 === Heat === Bed heaters 0 -1 -1 -1, chamber heaters -1 -1 -1 -1, ordering errs 0 === GCodes === Movement locks held by null HTTP is idle in state(s) 0 Telnet is idle in state(s) 0 File is idle in state(s) 0 USB is idle in state(s) 0 Aux is idle in state(s) 0 Trigger is idle in state(s) 0 Queue is idle in state(s) 0 LCD is idle in state(s) 0 Daemon is idle in state(s) 0 Autopause is idle in state(s) 0 Q0 segments left 0 Code queue 0 is empty === Filament sensors === Extruder 0 sensor: ok === Network === Slowest loop: 63.89ms; fastest: 0.00ms Responder states: HTTP(0) HTTP(0) HTTP(0) HTTP(0) FTP(0) Telnet(0) HTTP sessions: 1 of 8 = WiFi = Network state is active WiFi module is connected to access point Failed messages: pending 0, notready 0, noresp 0 WiFi firmware version 1.27 WiFi MAC address bc:dd:c2:89:a0:bb WiFi Vcc 3.38, reset reason Power up WiFi flash size 4194304, free heap 24736 WiFi IP address 192.168.1.163 WiFi signal strength -44dBm, mode 802.11n, reconnections 0, sleep mode modem Clock register 00002002 Socket states: 0 0 0 0 0 0 0 0
-
@OwenD were you using he latest commit of RRFLibraries from the 3.5-dev branch when you built RRF for Duet 2?
-
@dc42 said in Setting individual array element variables (V3.5.0b1):
@OwenD were you using he latest commit of RRFLibraries from the 3.5-dev branch when you built RRF for Duet 2?
Yes I believe so, downloaded a few hours ago.
Previously I was using 3.4-dev RRFLibraries, but had to change to 3.5-dev to get it to compile this time.
I use this batch file (entering 3.5-dev)@echo off set /p Version="Enter full version e.g. 3.4-dev : " cd C:\Eclipse\ del /f /s /q "C:\Eclipse\Firmware\*.*" rmdir /s /q "C:\Eclipse\Firmware" mkdir "C:\Eclipse\Firmware" cd "C:\Eclipse\Firmware" git clone https://github.com/Duet3D/ReprapFirmware.git -b %Version% git clone https://github.com/Duet3D/CANlib.git -b %Version% git clone https://github.com/Duet3D/CoreN2G -b %Version% git clone https://github.com/Duet3D/FreeRTOS -b 3.4-dev git clone https://github.com/Duet3D/RRFLibraries -b %Version% git clone https://github.com/Duet3D/DuetWiFiSocketServer -b dev echo ... echo **** press enter to exit **** pause >nul exit
-
@OwenD I found an issue when the Z probe has temperature coefficients specified in the G31 command, that could explain your reset. It should be fixed by the latest commit. Thanks for reporting this.
-
@dc42
Setting elements works for me too with your build, many thanks!
Now, before I convert all my code to use this style, is there something obviously bad/wrong with me defining my data like this? I know it's quite verbose, but this way it's easier to "see" the contents since these image data...;Digits global displayDigit = vector(10, null) ;0 set global.displayDigit[0] = vector(8, null) set global.displayDigit[0][0] = {0,1,1,1,1,1,1,0} set global.displayDigit[0][1] = {1,1,1,1,1,1,1,1} set global.displayDigit[0][2] = {1,1,1,0,0,1,1,1} set global.displayDigit[0][3] = {1,1,1,0,0,1,1,1} set global.displayDigit[0][4] = {1,1,1,0,0,1,1,1} set global.displayDigit[0][5] = {1,1,1,0,0,1,1,1} set global.displayDigit[0][6] = {1,1,1,1,1,1,1,1} set global.displayDigit[0][7] = {0,1,1,1,1,1,1,0} ;1 set global.displayDigit[1] = vector(8, null) set global.displayDigit[1][0] = {0,0,1,1,1,0,0,0} set global.displayDigit[1][1] = {0,0,1,1,1,1,0,0} set global.displayDigit[1][2] = {0,0,1,1,1,1,1,0} set global.displayDigit[1][3] = {0,0,1,1,1,0,0,0} set global.displayDigit[1][4] = {0,0,1,1,1,0,0,0} set global.displayDigit[1][5] = {0,0,1,1,1,0,0,0} set global.displayDigit[1][6] = {0,0,1,1,1,0,0,0} set global.displayDigit[1][7] = {0,0,1,1,1,0,0,0} ;2 set global.displayDigit[2] = vector(8, null) set global.displayDigit[2][0] = {0,1,1,1,1,1,1,0} set global.displayDigit[2][1] = {1,1,1,1,1,1,1,1} set global.displayDigit[2][2] = {1,1,1,0,0,1,1,1} set global.displayDigit[2][3] = {0,1,1,1,0,0,0,0} set global.displayDigit[2][4] = {0,0,0,1,1,1,0,0} set global.displayDigit[2][5] = {0,0,0,0,0,1,1,1} set global.displayDigit[2][6] = {1,1,1,1,1,1,1,1} set global.displayDigit[2][7] = {1,1,1,1,1,1,1,1} ;3 set global.displayDigit[3] = vector(8, null) set global.displayDigit[3][0] = {0,1,1,1,1,1,1,1} set global.displayDigit[3][1] = {1,1,1,1,1,1,1,1} set global.displayDigit[3][2] = {1,1,1,0,0,0,0,0} set global.displayDigit[3][3] = {0,1,1,1,1,1,1,1} set global.displayDigit[3][4] = {0,1,1,1,1,1,1,1} set global.displayDigit[3][5] = {1,1,1,0,0,0,0,0} set global.displayDigit[3][6] = {1,1,1,1,1,1,1,1} set global.displayDigit[3][7] = {0,1,1,1,1,1,1,1}
If there's no technical problem you can think of, I'd continue to use this style for my "image" data.
-
@Diamondback you could start with this:
global displayDigit = vector(10, vector(8,null))
I don't see any other way to improve it unless the individual vectors are sufficiently related so that you can calculate them algorithmically.