| Menu | JAQForum Ver 19.10.27 |
Forum Index : Microcontroller and PC projects : PicoMite V6.02.00 release candidates - Structured types
From the MMBasic manual I've explained this before, the interrupt allows you to feed the PIO at maximum rate. It tells you there is now a space in the fifo. It does not interrupt UNLESS the fifo has been full and now isn't Edited 2026-01-11 19:20 by matherp |
||||||
@Peter, I fully understand where the confusion around the TX interrupt comes from. When you look from ARM standpoint, the TX interrupt implementation is sound. The ARM runs at similar or higher frequency as the PIO, and can usew the interrupt to push the FIFO constantly full to the limits. This using the TX interrupt to take action. When executing MMBasic statements, the PIO is typically faster to read the data from FIFO than MMBasic can supply data. Hence the FIFO may never achieve FULL. You write 1 data element, but PIO has already taken one out. You never reach FULL, so you never get a TX interrupt. The TX interrupt is therefore not really usable for this purpose. Not for individual data elements. I have no idea if a better implementation is possible. In this case I would not rely on an interrupt, but use PIO (LEVEL ) to see how much would fit, and write that into FIFO in one PIO WRITE. And repeat this in a loop. If you insist on using interrupts, then execute this in a SETTICK controlled interrupt loop. But it is far better to not put this "refill" responsibility on MMBasic level. Use DMA,that is safer. Look at the implementations like the HUB75 driver. Earlier versions used individual DMA's, later versions us a DMA RING BUFFER. Volhout Edited 2026-01-11 21:08 by Volhout |
||||||
Could be useful for something like serial output or I2C but I agree there are other (better?) ways depending on the application. The facility is there to be used or not as the MMbasic prefers. |
||||||
Yes, the TX interrupt is really confusing. @Peter: I already understood that, but I'm trying to fully grasp it and create an example for it. However, it is a very special case in which the interrupt is only triggered. Volhout describes the problem surrounding it. I would classify it as a racing condition. I can't explain it any better than that. Thanks for your efforts. I have decided to learn and understand the interaction between PIO and MMBasic. Another question that concerns me is: Can I write only 8 bits to the FIFO? Or always only a 32-bit value? It would be really helpful not to always have to write a 32-bit value. Or to assemble it beforehand from four 8-bit values. In addition, a gap of n x 8-bit zeros is created when I want to add values. As I said, I'm still learning. With the DMA solution, I saw that you can specify this appropriately in memory reading. The manual also states the following for PIO WRITE: PIO WRITE pio, state_machine, count, data0 [,data1..] Writes the data elements to the pio and state machine specified. The write is blocking so the state machine needs to be able to take the data supplied NB: this command will probably need additional capability in future releases Addendum: I will answer myself as best I can. Currently, I can only write 32-bit values in FIFO. An update is not planned, as the value may be pulled at that moment and the bit pointer would have to be manipulated/updated. Is that even possible? So, do I have to ensure in PIO that the remaining 24 bits are discarded or ignored if I want 8-bit/1-byte values? Edited 2026-01-12 00:40 by homa |
||||||
Hi Homa, PIO does not have to use the 32 bits. A pull instruction copies 32 bits in OSR, but the PIO program or configuration decides how many bits it uses. So write a byte to FIFO (24 bits waste, 8 used), and in the PIO program decide to only use 8 bits (using the OUT instruction, with destination GPIO or X or Y or...). An alternative could be to PACK multiple 8 bit values in 32 bits, and write a PIO program that uses. Search the manual for PACK. .label return_here PULL OUT 8 bits (the first 8) OUT 8 bits OUT 8 bits OUT 8 bits JMP return_here Volhout P.S. there are provisions to automate this. You can set the threshold how many bits are shifted out of OSR (i.e. 17) when an automatic PULL happens, and the OSR is overwritten. You could use this threshold at 8, and use it to transfer bytes, but the value written in FIFO must be a 32 bit value. That is hardware. Edited 2026-01-12 04:51 by Volhout |
||||||
Found an "error" in the GPS_parse function in the GPS.c source file. If the NMEA checksum is missing, the message passes the checksum test. The attached GPS.c file will discard the NMEA message if the checksum "*" delimiter is missing. GPS.zip |
||||||
V6.02.00RC5 PicoMiteV6.02.00RC5.zip Improves error handling of pre-processor errors - things like duplicate function names. These will now give the same sort of message as a program error and position the cursor when entering the editor Fixes GPS as per Sasquatch's message Re-engineers SELECT CASE to avoid memory issues. If you use SELECT CASE please test thoroughly. Adds the SUN as a valid body in commands ASTRO and STAR (RP2350 only) GPS_Astro_Reference.pdf My select case test program ' SELECT CASE Memory Test Program ' Tests temp memory cleanup with many CASE statements ' Matches at positions: 5, 50, 100, 150, 199, and CASE ELSE OPTION EXPLICIT DIM test%, pass%, fail% pass% = 0 fail% = 0 PRINT "SELECT CASE Memory Test" PRINT "========================" ' Test 1: Match early (position 5) test% = 1 PRINT "Test 1: Match at position 5... "; SelectTest("case005") IF pass% <> 1 THEN fail% = fail% + 1 : PRINT "FAIL" ELSE PRINT "PASS" ' Test 2: Match at position 50 test% = 2 pass% = 0 PRINT "Test 2: Match at position 50... "; SelectTest("case050") IF pass% <> 1 THEN fail% = fail% + 1 : PRINT "FAIL" ELSE PRINT "PASS" ' Test 3: Match at position 100 test% = 3 pass% = 0 PRINT "Test 3: Match at position 100... "; SelectTest("case100") IF pass% <> 1 THEN fail% = fail% + 1 : PRINT "FAIL" ELSE PRINT "PASS" ' Test 4: Match at position 150 test% = 4 pass% = 0 PRINT "Test 4: Match at position 150... "; SelectTest("case150") IF pass% <> 1 THEN fail% = fail% + 1 : PRINT "FAIL" ELSE PRINT "PASS" ' Test 5: Match at position 199 (near end) test% = 5 pass% = 0 PRINT "Test 5: Match at position 199... "; SelectTest("case199") IF pass% <> 1 THEN fail% = fail% + 1 : PRINT "FAIL" ELSE PRINT "PASS" ' Test 6: No match - should hit CASE ELSE test% = 6 pass% = 0 PRINT "Test 6: CASE ELSE (no match)... "; SelectTest("nomatch") IF pass% <> 2 THEN fail% = fail% + 1 : PRINT "FAIL" ELSE PRINT "PASS" ' Test 7: Run multiple times to check for memory leaks PRINT "Test 7: Repeated calls (100x) to check memory..."; DIM i% FOR i% = 1 TO 100 SelectTest("case100") NEXT i% PRINT " PASS" ' Test 8: Integer SELECT CASE with many options PRINT "Test 8: Integer SELECT with 200 cases... "; pass% = 0 SelectTestInt(150) IF pass% <> 1 THEN fail% = fail% + 1 : PRINT "FAIL" ELSE PRINT "PASS" PRINT "========================" PRINT "Tests complete. Failures: " + STR$(fail%) PRINT "Check MEMORY command for heap usage" MEMORY END SUB SelectTest(val$) LOCAL result$ result$ = "" SELECT CASE val$ CASE "case001": result$ = "001" CASE "case002": result$ = "002" CASE "case003": result$ = "003" CASE "case004": result$ = "004" CASE "case005": result$ = "005" CASE "case006": result$ = "006" CASE "case007": result$ = "007" CASE "case008": result$ = "008" CASE "case009": result$ = "009" CASE "case010": result$ = "010" CASE "case011": result$ = "011" CASE "case012": result$ = "012" CASE "case013": result$ = "013" CASE "case014": result$ = "014" CASE "case015": result$ = "015" CASE "case016": result$ = "016" CASE "case017": result$ = "017" CASE "case018": result$ = "018" CASE "case019": result$ = "019" CASE "case020": result$ = "020" CASE "case021": result$ = "021" CASE "case022": result$ = "022" CASE "case023": result$ = "023" CASE "case024": result$ = "024" CASE "case025": result$ = "025" CASE "case026": result$ = "026" CASE "case027": result$ = "027" CASE "case028": result$ = "028" CASE "case029": result$ = "029" CASE "case030": result$ = "030" CASE "case031": result$ = "031" CASE "case032": result$ = "032" CASE "case033": result$ = "033" CASE "case034": result$ = "034" CASE "case035": result$ = "035" CASE "case036": result$ = "036" CASE "case037": result$ = "037" CASE "case038": result$ = "038" CASE "case039": result$ = "039" CASE "case040": result$ = "040" CASE "case041": result$ = "041" CASE "case042": result$ = "042" CASE "case043": result$ = "043" CASE "case044": result$ = "044" CASE "case045": result$ = "045" CASE "case046": result$ = "046" CASE "case047": result$ = "047" CASE "case048": result$ = "048" CASE "case049": result$ = "049" CASE "case050": result$ = "050" CASE "case051": result$ = "051" CASE "case052": result$ = "052" CASE "case053": result$ = "053" CASE "case054": result$ = "054" CASE "case055": result$ = "055" CASE "case056": result$ = "056" CASE "case057": result$ = "057" CASE "case058": result$ = "058" CASE "case059": result$ = "059" CASE "case060": result$ = "060" CASE "case061": result$ = "061" CASE "case062": result$ = "062" CASE "case063": result$ = "063" CASE "case064": result$ = "064" CASE "case065": result$ = "065" CASE "case066": result$ = "066" CASE "case067": result$ = "067" CASE "case068": result$ = "068" CASE "case069": result$ = "069" CASE "case070": result$ = "070" CASE "case071": result$ = "071" CASE "case072": result$ = "072" CASE "case073": result$ = "073" CASE "case074": result$ = "074" CASE "case075": result$ = "075" CASE "case076": result$ = "076" CASE "case077": result$ = "077" CASE "case078": result$ = "078" CASE "case079": result$ = "079" CASE "case080": result$ = "080" CASE "case081": result$ = "081" CASE "case082": result$ = "082" CASE "case083": result$ = "083" CASE "case084": result$ = "084" CASE "case085": result$ = "085" CASE "case086": result$ = "086" CASE "case087": result$ = "087" CASE "case088": result$ = "088" CASE "case089": result$ = "089" CASE "case090": result$ = "090" CASE "case091": result$ = "091" CASE "case092": result$ = "092" CASE "case093": result$ = "093" CASE "case094": result$ = "094" CASE "case095": result$ = "095" CASE "case096": result$ = "096" CASE "case097": result$ = "097" CASE "case098": result$ = "098" CASE "case099": result$ = "099" CASE "case100": result$ = "100" CASE "case101": result$ = "101" CASE "case102": result$ = "102" CASE "case103": result$ = "103" CASE "case104": result$ = "104" CASE "case105": result$ = "105" CASE "case106": result$ = "106" CASE "case107": result$ = "107" CASE "case108": result$ = "108" CASE "case109": result$ = "109" CASE "case110": result$ = "110" CASE "case111": result$ = "111" CASE "case112": result$ = "112" CASE "case113": result$ = "113" CASE "case114": result$ = "114" CASE "case115": result$ = "115" CASE "case116": result$ = "116" CASE "case117": result$ = "117" CASE "case118": result$ = "118" CASE "case119": result$ = "119" CASE "case120": result$ = "120" CASE "case121": result$ = "121" CASE "case122": result$ = "122" CASE "case123": result$ = "123" CASE "case124": result$ = "124" CASE "case125": result$ = "125" CASE "case126": result$ = "126" CASE "case127": result$ = "127" CASE "case128": result$ = "128" CASE "case129": result$ = "129" CASE "case130": result$ = "130" CASE "case131": result$ = "131" CASE "case132": result$ = "132" CASE "case133": result$ = "133" CASE "case134": result$ = "134" CASE "case135": result$ = "135" CASE "case136": result$ = "136" CASE "case137": result$ = "137" CASE "case138": result$ = "138" CASE "case139": result$ = "139" CASE "case140": result$ = "140" CASE "case141": result$ = "141" CASE "case142": result$ = "142" CASE "case143": result$ = "143" CASE "case144": result$ = "144" CASE "case145": result$ = "145" CASE "case146": result$ = "146" CASE "case147": result$ = "147" CASE "case148": result$ = "148" CASE "case149": result$ = "149" CASE "case150": result$ = "150" CASE "case151": result$ = "151" CASE "case152": result$ = "152" CASE "case153": result$ = "153" CASE "case154": result$ = "154" CASE "case155": result$ = "155" CASE "case156": result$ = "156" CASE "case157": result$ = "157" CASE "case158": result$ = "158" CASE "case159": result$ = "159" CASE "case160": result$ = "160" CASE "case161": result$ = "161" CASE "case162": result$ = "162" CASE "case163": result$ = "163" CASE "case164": result$ = "164" CASE "case165": result$ = "165" CASE "case166": result$ = "166" CASE "case167": result$ = "167" CASE "case168": result$ = "168" CASE "case169": result$ = "169" CASE "case170": result$ = "170" CASE "case171": result$ = "171" CASE "case172": result$ = "172" CASE "case173": result$ = "173" CASE "case174": result$ = "174" CASE "case175": result$ = "175" CASE "case176": result$ = "176" CASE "case177": result$ = "177" CASE "case178": result$ = "178" CASE "case179": result$ = "179" CASE "case180": result$ = "180" CASE "case181": result$ = "181" CASE "case182": result$ = "182" CASE "case183": result$ = "183" CASE "case184": result$ = "184" CASE "case185": result$ = "185" CASE "case186": result$ = "186" CASE "case187": result$ = "187" CASE "case188": result$ = "188" CASE "case189": result$ = "189" CASE "case190": result$ = "190" CASE "case191": result$ = "191" CASE "case192": result$ = "192" CASE "case193": result$ = "193" CASE "case194": result$ = "194" CASE "case195": result$ = "195" CASE "case196": result$ = "196" CASE "case197": result$ = "197" CASE "case198": result$ = "198" CASE "case199": result$ = "199" CASE "case200": result$ = "200" CASE ELSE: result$ = "ELSE" END SELECT IF result$ = "ELSE" THEN pass% = 2 ELSEIF result$ <> "" THEN pass% = 1 ENDIF END SUB SUB SelectTestInt(val%) LOCAL result% result% = -1 SELECT CASE val% CASE 1: result% = 1 CASE 2: result% = 2 CASE 3: result% = 3 CASE 4: result% = 4 CASE 5: result% = 5 CASE 6: result% = 6 CASE 7: result% = 7 CASE 8: result% = 8 CASE 9: result% = 9 CASE 10: result% = 10 CASE 11: result% = 11 CASE 12: result% = 12 CASE 13: result% = 13 CASE 14: result% = 14 CASE 15: result% = 15 CASE 16: result% = 16 CASE 17: result% = 17 CASE 18: result% = 18 CASE 19: result% = 19 CASE 20: result% = 20 CASE 21: result% = 21 CASE 22: result% = 22 CASE 23: result% = 23 CASE 24: result% = 24 CASE 25: result% = 25 CASE 26: result% = 26 CASE 27: result% = 27 CASE 28: result% = 28 CASE 29: result% = 29 CASE 30: result% = 30 CASE 31: result% = 31 CASE 32: result% = 32 CASE 33: result% = 33 CASE 34: result% = 34 CASE 35: result% = 35 CASE 36: result% = 36 CASE 37: result% = 37 CASE 38: result% = 38 CASE 39: result% = 39 CASE 40: result% = 40 CASE 41: result% = 41 CASE 42: result% = 42 CASE 43: result% = 43 CASE 44: result% = 44 CASE 45: result% = 45 CASE 46: result% = 46 CASE 47: result% = 47 CASE 48: result% = 48 CASE 49: result% = 49 CASE 50: result% = 50 CASE 51: result% = 51 CASE 52: result% = 52 CASE 53: result% = 53 CASE 54: result% = 54 CASE 55: result% = 55 CASE 56: result% = 56 CASE 57: result% = 57 CASE 58: result% = 58 CASE 59: result% = 59 CASE 60: result% = 60 CASE 61: result% = 61 CASE 62: result% = 62 CASE 63: result% = 63 CASE 64: result% = 64 CASE 65: result% = 65 CASE 66: result% = 66 CASE 67: result% = 67 CASE 68: result% = 68 CASE 69: result% = 69 CASE 70: result% = 70 CASE 71: result% = 71 CASE 72: result% = 72 CASE 73: result% = 73 CASE 74: result% = 74 CASE 75: result% = 75 CASE 76: result% = 76 CASE 77: result% = 77 CASE 78: result% = 78 CASE 79: result% = 79 CASE 80: result% = 80 CASE 81: result% = 81 CASE 82: result% = 82 CASE 83: result% = 83 CASE 84: result% = 84 CASE 85: result% = 85 CASE 86: result% = 86 CASE 87: result% = 87 CASE 88: result% = 88 CASE 89: result% = 89 CASE 90: result% = 90 CASE 91: result% = 91 CASE 92: result% = 92 CASE 93: result% = 93 CASE 94: result% = 94 CASE 95: result% = 95 CASE 96: result% = 96 CASE 97: result% = 97 CASE 98: result% = 98 CASE 99: result% = 99 CASE 100: result% = 100 CASE 101: result% = 101 CASE 102: result% = 102 CASE 103: result% = 103 CASE 104: result% = 104 CASE 105: result% = 105 CASE 106: result% = 106 CASE 107: result% = 107 CASE 108: result% = 108 CASE 109: result% = 109 CASE 110: result% = 110 CASE 111: result% = 111 CASE 112: result% = 112 CASE 113: result% = 113 CASE 114: result% = 114 CASE 115: result% = 115 CASE 116: result% = 116 CASE 117: result% = 117 CASE 118: result% = 118 CASE 119: result% = 119 CASE 120: result% = 120 CASE 121: result% = 121 CASE 122: result% = 122 CASE 123: result% = 123 CASE 124: result% = 124 CASE 125: result% = 125 CASE 126: result% = 126 CASE 127: result% = 127 CASE 128: result% = 128 CASE 129: result% = 129 CASE 130: result% = 130 CASE 131: result% = 131 CASE 132: result% = 132 CASE 133: result% = 133 CASE 134: result% = 134 CASE 135: result% = 135 CASE 136: result% = 136 CASE 137: result% = 137 CASE 138: result% = 138 CASE 139: result% = 139 CASE 140: result% = 140 CASE 141: result% = 141 CASE 142: result% = 142 CASE 143: result% = 143 CASE 144: result% = 144 CASE 145: result% = 145 CASE 146: result% = 146 CASE 147: result% = 147 CASE 148: result% = 148 CASE 149: result% = 149 CASE 150: result% = 150 CASE 151: result% = 151 CASE 152: result% = 152 CASE 153: result% = 153 CASE 154: result% = 154 CASE 155: result% = 155 CASE 156: result% = 156 CASE 157: result% = 157 CASE 158: result% = 158 CASE 159: result% = 159 CASE 160: result% = 160 CASE 161: result% = 161 CASE 162: result% = 162 CASE 163: result% = 163 CASE 164: result% = 164 CASE 165: result% = 165 CASE 166: result% = 166 CASE 167: result% = 167 CASE 168: result% = 168 CASE 169: result% = 169 CASE 170: result% = 170 CASE 171: result% = 171 CASE 172: result% = 172 CASE 173: result% = 173 CASE 174: result% = 174 CASE 175: result% = 175 CASE 176: result% = 176 CASE 177: result% = 177 CASE 178: result% = 178 CASE 179: result% = 179 CASE 180: result% = 180 CASE 181: result% = 181 CASE 182: result% = 182 CASE 183: result% = 183 CASE 184: result% = 184 CASE 185: result% = 185 CASE 186: result% = 186 CASE 187: result% = 187 CASE 188: result% = 188 CASE 189: result% = 189 CASE 190: result% = 190 CASE 191: result% = 191 CASE 192: result% = 192 CASE 193: result% = 193 CASE 194: result% = 194 CASE 195: result% = 195 CASE 196: result% = 196 CASE 197: result% = 197 CASE 198: result% = 198 CASE 199: result% = 199 CASE 200: result% = 200 CASE ELSE: result% = 0 END SELECT IF result% = val% THEN pass% = 1 END SUB |
||||||
I've been experimenting again with Lizby's database experiments... I don't know if the following should work, or if it's "too complicated" for the 'EXECUTE' command? Option Base 1 Option Explicit Option Escape 'Next line throws error if enabled: "Error: Invalid member definition in TYPE" 'Type TPers phone As integer surname As string Length 8 name As string Length 7 pad As string Length 2 End Type Dim TypeNam1$ As String = "TPerson\n\r" Dim TypeDef1$ As String = "Type " TypeDef1$ = TypeDef1$ + TypeNam1$ TypeDef1$ = TypeDef1$ + "phone As integer\n\r" TypeDef1$ = TypeDef1$ + "surname As string Length 8\n\r" TypeDef1$ = TypeDef1$ + "name As string Length 7\n\r" TypeDef1$ = TypeDef1$ + "padding As string Length 2\n\r" TypeDef1$ = TypeDef1$ + "End Type\n\r" Dim TypeDim1$ As String TypeDim1$ = "Dim people(2) As " + TypeNam1$ Print TypeDef1$ Print TypeDim1$ 'Next line throws error: "Error : No matching END TYPE" Execute TypeDef1$ Execute TypeDim1$ Print Struct(Type, "TPerson") End I also don't know if the type definition commented out in the example above should work as a one-liner?: Type TPers phone As integer surname As string Length 8 name As string Length 7 pad As string Length 2 End Type Perhaps one could use ',' as a separator for the one-liner type, even if the syntax then differs from Microsoft's QBasic? Type TPers, phone As integer, surname As string, Length 8, name As string Length 7, pad As string Length 2, End Type But if it did work, it would be fantastic for Lizby's database experiments! https://www.thebackshed.com/forum/ViewTopic.php?FID=16&TID=18546 Another way to make the database more "generic" would be a "database generator program" that uses a menu to determine the fields of the table(s) and then outputs a finished BASIC program to a file. Regards. |
||||||
Types are defined before the program is run in the same way as subroutines. This can't possibly work any more than trying to define a subroutine using execute could. |
||||||
Ah, OK, that's what I suspected – nothing can be done about it then. Another possibility would be to have the type definitions in an #include file. But that would only work with 'CMM2 LOAD'. Then one have to use the "program generator" method for a generic database-system. |
||||||
Error: Invalid address - resetting This happened after a few minutes with the part of the program that previously worked fine. In the past, I had to adjust the I2C speed on an RP2040: OPTION SYSTEM I2C GP4, GP5, SLOW. With the RP2350, I now see that the screen is completely scrambled when using SLOW with this part of the program. Perhaps something changed with FAST and SLOW? I changed the Byte in the LCD I2C subs to AByte. But then I also get "Error: Invalid address - resetting" with V6.02.00RC4. The program stops. If I change it back to OPTION SYSTEM I2C GP4, GP5, the LCD screen displays normally until the message "Error: Invalid address - resetting" with TeraTerm is displayed, and the program stops. With the RP2040 running V6.01.00 and OPTION SYSTEM I2C GP4, GP5, there was no problem with the LCD screen and no "Error: Invalid address - resetting" error. With OPTION SYSTEM I2C GP4, GP5, and SLOW, the LCD screen was mixed. The program continued to run. (Previously, this was without SLOW.) With the RP2040 running V6.02.00RC4 and OPTION SYSTEM I2C GP4, GP5, there was no problem with the LCD screen and no "Error: Invalid address - resetting" error. With OPTION SYSTEM I2C GP4, GP5, and SLOW, the LCD screen was mixed. The program continued to run. (Previously, this was without SLOW.) Later, I tested with Byte on an RP2040 and RP2350A V6.02.00RC4 and still no problems, so the "Error: Invalid address - resetting" error is not the problem, but with the RP2350, this message appeared after a few minutes. Also the OPTION RTC AUTO ENABLE is sometimes removed but I can't recreate it anymore? If you change the bus speed for I2C to SLOW (100kHz manual), the LCD output is no longer correct. So, apparently something has changed in the FAST (Standard 400kHz manual) and SLOW (100kHz manual) settings for OPTION SYSTEM I2C? The "Error: Invalid address - resetting" only occurs with the RP2350 series. When I switch from V6.01.00 to V6.02.00 with an RP2040, I can no longer write to or read from A:. "Error: Error during device operation," so A: must first be formatted (DRIVE "A:/FORMAT"). > option list PicoMite MMBasic RP2350A V6.02.00RC4 OPTION SYSTEM SPI GP10,GP11,GP12 OPTION SYSTEM I2C GP4,GP5 OPTION FLASH SIZE 16777216 OPTION COLOURCODE ON OPTION HEARTBEAT OFF OPTION PICO OFF OPTION CPUSPEED (KHz) 200000 OPTION DISPLAY 50, 100 OPTION SDCARD GP15 OPTION RTC AUTO ENABLE OPTION F1 FLASH RUN 1 '*** DEMOKAS *** Const Buiten_temp = 5.6 Const binnen_temp = 19.2 Const Raamstand_m = 2.0 '*** Hier de speciale tekens *** LCDI2C_Init &H20, 1, 0, 2, 3 'I2CAddr: &H20=20x4 LCDI2C, &H38=16x2 LCDI2C LCDI2C_CLEAR LCDI2C_BackLightOn LCDI2C_CMD(64) 'Chr$(0) LCDI2C_DATA(7): LCDI2C_DATA(5): LCDI2C_DATA(7): LCDI2C_DATA(0)'Gradenteken B1-4 LCDI2C_DATA(0): LCDI2C_DATA(0): LCDI2C_DATA(0): LCDI2C_DATA(0)'Gradenteken B5-8 LCDI2C_CMD(80) 'Chr$(2) LCDI2C_DATA(0): LCDI2C_DATA(0): LCDI2C_DATA(0): LCDI2C_DATA(0)'LEEG teken B1-4 LCDI2C_DATA(0): LCDI2C_DATA(0): LCDI2C_DATA(0): LCDI2C_DATA(0)'LEEG teken B5-8 Do Beeld 'Bouw met een I2C LCD2004 display het menu op. Pause 500 Loop '*** Bouw het menu beeld op aan het begin van het programma. ***" Sub Beeld LCDI2C 1, 1, "BuitenTemp.: C" LCDI2C 1,15, Str$(Buiten_temp, 2, 1) LCDI2C 1,19, Chr$(0) LCDI2C 2, 1, "BinnenTemp.: C" LCDI2C 2,15, Str$(Binnen_temp, 2, 1) LCDI2C 2,19, Chr$(0) LCDI2C 3, 1, "Raamstand : %" LCDI2C 3,15, Str$(Raamstand_m, 2, 1) LCDI2C 4, 1, "di" LCDI2C 4, 4, Left$(Date$, 10) LCDI2C 4,15, Left$(Time$, 5) End Sub '*** LCDI2C subroutines. **** Sub LCDI2C(LineNum, CharPos, Text$) Local I If LineNum = 1 Then I = (&H80 + CharPos - 1) If LineNum = 2 Then I = (&HC0 + CharPos - 1) If LineNum = 3 Then I = (&H94 + CharPos - 1) If LineNum = 4 Then I = (&HD4 + CharPos - 1) LCDI2C_CMD(I) For I = 1 To Len(Text$) LCDI2C_DATA(Asc(Mid$(Text$, I, 1))) Next I End Sub ' Sub LCDI2C_Clear() LCDI2C_CMD(&H01) Pause 3 End Sub ' Sub LCDI2C_Init I2CAddr, NibPos, RSBitNo, ENBitNo, BLBitNo Dim LCDI2C_BackLight LCDI2C_BackLight = 2 ^ BLBitNo Dim LCDI2C_LCDBackLight LCDI2C_LCDBackLight = LCDI2C_BackLight Dim LCDI2C_I2CAddr LCDI2C_I2CAddr = I2CAddr Dim LCDI2C_RSDataMask LCDI2C_RSDataMask = 2 ^ RSBitNo Dim LCDI2C_EMask LCDI2C_EMask = 2 ^ ENBitNo Dim LCDI2C_NibPos LCDI2C_NibPos = NiBPos LCDI2C_CMD(&H33) LCDI2C_CMD(&H32) LCDI2C_CMD(&H28) LCDI2C_CMD(&H0C) LCDI2C_CMD(&H06) LCDI2C_CMD(&H01) LCDI2C_BackLightOff() End Sub ' Sub LCDI2C_Close() I2C CLOSE End Sub ' Sub LCDI2C_BacklightOn LCDI2C_LCDBackLight = LCDI2C_Backlight LCDI2C_WireWrite(0) End Sub ' Sub LCDI2C_BacklightOff LCDI2C_LCDBackLight = &H00 LCDI2C_WireWrite(0) End Sub ' Sub LCDI2C_CMD(AByte) LCDI2C_DirectSend(AByte And &HF0) LCDI2C_DirectSend((AByte And &H0F) * 16) End Sub ' Sub LCDI2C_DATA(AByte) LCDI2C_DirectSend((AByte And &HF0) Or LCDI2C_RSDataMask) LCDI2C_DirectSend(((AByte And &H0F) * 16) Or LCDI2C_RSDataMask) End Sub ' Sub LCDI2C_DirectSend(AByte) Local B, B1 If LCDI2C_NibPos = 0 Then B1 = AByte \ 16 Else B1 = AByte EndIf B = B1 Or LCDI2C_EMask Or LCDI2C_LCDBackLight I2C WRITE LCDI2C_I2CAddr, 0, 1, B I2C WRITE LCDI2C_I2CAddr, 0, 1, B1 Or LCDI2C_LCDBackLight End Sub ' Sub LCDI2C_WireWrite(AByte) I2C WRITE LCDI2C_I2CAddr, 0, 1, AByte Or LCDI2C_LCDBackLight End Sub Kind regards, Jan. |
||||||
I don't have one of these display so difficult to replicate. Please disable RTC AUTO and see if the problem still occurs |
||||||
Could it be the latest addition of the new RTC module? If you install the PicoMite MMBasic RP2350A V6.02.00RC4 firmware, use the option list, and no pins are connected, and load the DEMOKAS.bas program, it will also happen after 4 minutes when Windows notifies you with the message "Error: Invalid address - resetting." When I remove the Raspberry Pi Pico module from its holder, the RTC AUTO ENABLE option is removed from the list. When I then run the test, the program stops after about 4 minutes. If I replace the module without the RTC AUTO ENABLE option in the list and start the program, it continues to work, but for much longer, and then stops after 12 minutes. I can easily follow this because the RTC time on the LCD screen starts at 00:00. Kind regards, Jan. Edited 2026-01-14 04:13 by JanVolk |
||||||
No. I've even set the RTC background update rate to 60 seconds and it has run for 30mins with no issue (no display connected) |
||||||
Okay. Then I'll do some more research with flash_nuke and another RP2350 module and another DS3231. Thanks in advance. |
||||||
This with colons alone at the command prompt does not fail for me: Type: TPers phone As integer: surname As string Length 8: name As string Length 7: pad As string Length 2: End Type (Don't know about any of the other issues--but I don't see how to generalize a database manager from a structure) |
||||||
Ah - good to know and a great tip! I also briefly considered whether ':' could work as a separator, but I didn't try it because I thought ':' separates statements and the entire "block" 'Type typeName memberDefinition ... End Type' would count as one statement. I tried the "one-liner" because I thought it might simplify 'EXECUTE'. You could write a "database editor" in BASIC where you can enter tables using their fields (field names and types) and design forms. You could also design reports. This could even be done with a GUI. The information could then be saved as a "project file," for example, as a JSON or XML file. From this "project," you could then generate the MMBasic code using an "export function." This code would contain the struct types, the table DIMs, and the corresponding SUBs. The whole thing could then be combined with an existing "framework application" (by copying the files together) to create a complete BASIC database program. Regards, bfwolf |
||||||
Setting up types at the comand prompt is fine but they are overwritten when you run a program |
||||||
Hi @Peter: If that was referring to my previous post, you probably misunderstood me. I understand that you can define types as "one-liners" in the command line — for example, for testing — but that they are deleted with 'RUN' because RUN deletes all variables, and therefore presumably also types. My idea is to write a program ("database generator") that exports an MMBasic program with appropriate types, forms, etc., to the file system based on user-defined table structures. From there, it can be loaded and run. The exported program could then potentially even be started directly from the database generator using 'CHAIN' (or 'RUN'?). |
||||||
Yes that should work. Have done a similar thing using RUN. The program starts in "Learning Mode" by copying itself to A: then goes through the learning process, appending the new data to the disc copy. It then RUNs the disc copy which detects the new data and switches to "Operating Mode". |
||||||
| The Back Shed's forum code is written, and hosted, in Australia. |