![]() |
Forum Index : Microcontroller and PC projects : ON ERROR SKIP and Interrupts
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 675 |
I am a bit confused! I encountered this error while taking an image via "save image" command within my program (pico VGA): Error : A hard error occurred in the low level disk I/O layer It is the first time this happened, after that the sd card was ok, no corrupted files etc. BUT How can I prevent my program from being stopped by this hardware(?) issue with Peters suggestion of better code...? The point is, that I can live without a screen picture but my program should return to the main function, which is reading sensor states! And my whole program crashes just because some external hardware failure? Isn't ON ERROR a perfect solution? I am confused, error handling is such an important thing and now I am reading it is bad? Greetings Daniel Edited 2022-04-10 15:41 by Amnesie |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7937 |
Using ON ERROR is fine for its intended use, IMHO, which applies to this case. This can be a hardware fault (supply voltage to SDcard during write?), which you can never guard against normally. As hardware is disconnected from software you don't know what it's going to do. ON ERROR allows some handling of the vagaries of hardware (which can literally do anything as it might be connected incorrectly or even missing completely). On the other hand, you always know (or should do) what the software will do - it's predictable and you know its limitations. Hence, there are no errors in the results of a well-written software routine - the routine(s) should have taken care of those. Using ON ERROR is a get-out which some use to avoid writing error-trapping routines. Fine, it often works and often produces smaller code, but it's not good programming practice and can be incomprehensible to someone trying to maintain the programme. A typical naughty use is in doing something like ON ERROR IGNORE when the fault condition is something mundane like trying to plot out of the screen area - that should be handled by the plot routine - it's not an error. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
It is meaningless to use ON ERROR for things like disk errors as they are largely non-recoverable. If you get the "low level disk error" then using ON ERROR can keep your program running but to what effect? Presumably there was a reason you were trying to write to the disk. Likewise, trying to write with the disk missing. I can just about accept that if the disk is full you could have code to delete something to free up space but that is hardly a generic solution. On versions of MMBasic without things like MM.INFO(exists file fname$) the easiest way to test for a file being there without an error is the DIR$ function Jim: can you explain more with a simple example so I can fix - thanks |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
I thought I was going mad for a while. These two work: 'this works IF MM.INFO$(SDCARD) = "Ready" THEN OPEN "testit.txt" FOR OUTPUT AS #1 CLOSE #1 PRINT MM.INFO$(FILESIZE "testit.txt") ENDIF 'this works IF MM.INFO$(SDCARD) = "Ready" THEN OPEN "testit.txt" FOR OUTPUT AS #1 CLOSE #1 PRINT MM.INFO$(FILESIZE "wrong.nam") 'nonexisting file junk$ = dir$("",file) PRINT MM.INFO$(FILESIZE "testit.txt") ENDIF but this fails: 'this fails IF MM.INFO$(SDCARD) = "Ready" THEN OPEN "testit.txt" FOR OUTPUT AS #1 CLOSE #1 PRINT MM.INFO$(FILESIZE "wrong.nam") 'nonexisting file PRINT MM.INFO$(FILESIZE "testit.txt") ENDIF V5.7.04RC2 but similar on earlier firmware. Edit: First call works but after the other filesize call, the one to the zero size fails 'this fails IF MM.INFO$(SDCARD) = "Ready" THEN OPEN "testit.txt" FOR OUTPUT AS #1 CLOSE #1 PRINT MM.INFO$(FILESIZE "testit.txt") 'works pRINT MM.INFO$(FILESIZE "wrong.nam") 'nonexisting file PRINT MM.INFO$(FILESIZE "testit.txt") 'error ENDIF Jim Edited 2022-04-10 18:07 by TassyJim VK7JH MMedit |
||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 675 |
Peter, I think you get me wrong or don't understand what my intention is. You are right, that there is a reason for a failure or error and you have to fix it. For example, there is ALWAYS a reason a fuse blows up and you shouldn't replace it without fixing the reason that caused it. BUT: My mindset in engineering isn't to abuse some "ON ERROR" function for my (of course still weak MMBASIC knowledge) to get things just done "somehow", but to have a robust program, which keeps it's main functions alive while be able to shut down hardware or software features which are not that important. I'll give you an example where this failure with the SD card came up: My Geiger Counter program saves an image of the graph / plot just as a "backup". But don't you agree with me, that it is absolutly important, that it will continue the main function of alarming me if the radiation gets too high? This is the only reason to ask why ON ERROR is bad practise... I can live for that moment with the sd failure. |
||||
Turbo46![]() Guru ![]() Joined: 24/12/2017 Location: AustraliaPosts: 1642 |
MMBasic DOS Version has no DIR$ function. I suppose I could use the FILES command and ask the user: "Do you see the file called "; f$; " Press Y or N" But I don't think so. Bill Keep safe. Live long and prosper. |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3378 |
I ask as an appreciative and frequent user of MMBasic DOS: Is there any functional reason to use it now instead of MMB4W? PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
toml_12953 Guru ![]() Joined: 13/02/2015 Location: United StatesPosts: 442 |
If the problem is a missing disk, you can use ON ERROR to inform the user to insert the proper disk. If it really is a hardware error, you can print a more detailed error message. Which of these would a user rather see? I/O Error on line 47 or There was a disk read error on line 47 while trying to access ACCTS_PAYABLE_INFILE. Please call Tech Support at xxxx and read them this message. |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7937 |
I don't think Peter has any intention of removing ON ERROR etc., he's merely saying that it seems rather pointless if the error is unrecoverable. IMHO it has its place, but it's one of those things where you should think carefully about whether there might be a better way to handle it. Remember that MMBasic is more flexible in many ways than GWBASIC. +++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++ (Thanks Pterry. :) ) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
I don't think it's completely useless: 'Mandelbrot Explorer V1.4 for Color Maximite 2 10/26/2020 'By the Sasquatch '... 'Check for Wii Nunchuk On Error Skip 1 Wii Nunchuk Open If MM.ERRNO = 0 Then If Nunchuk(T) = &HA4200000 Then 'Check for original style nunchuk HaveChuk = True Else Wii Nunchuk Close End If End If If Not HaveChuk Then 'Check for Wii Classic Controller On Error Skip 1 Wii Classic Open If MM.ERRNO = 0 Then If Classic(T) = &HA4200101 Then 'Check for Classic HaveClassic = True Else Wii Classic Close End If End If End If 'Check for Mouse on I2C2 Pin27 SDA, Pin28 SCK On Error Skip 1 Controller Mouse Open If MM.ERRNO = 0 Then HaveMouse = True OldMouseX = Mouse(X) OldMouseY = Mouse(Y) End If '... Regards Michael causality ≠correlation ≠coincidence |
||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 675 |
It is NOT pointless, It can be dangerous to always generalize things. Above I mentioned my intention of using "ON ERROR" to shut down a hardware feature / software feature, which has less priority than my main function of alarming me, when radiation is getting crictical (Geiger counter), instead of crashing with an error to the prompt. I mean; tell me what is pointless about this? I came from an engineering point of view, in which shutting down features and keep alive the most important part of an application isn't even a standard but the norm. You find this in avionic applications, medical applications and so on. You may say, okay than don't use MMBASIC for it. But it is just wrong to say "it is pointless", because it can't recover. No it can not, but it can keep important tasks alive until you fix it. This even hasn't to do with different opinions. As a matter of fact error handling in case of critical crashes is important and I am really interested in an answer, how it should be done without it (in my case)! This is why I would like to lern to do it better in BASIC, so again, is there something I am missing (which, of course is possible since I am a beginner in this language / dialect.) No only in Germany it should be done as I said, the "medical device and diagnostic industry" has pointed out this, too. See (6. Prevent the Disabling of Life-Critical Alarms.) https://www.mddionline.com/news/eleven-keys-designing-error-resistant-medical-devices P.S. No, I do not built a life saving device upon the picoMite :) But it does make fun to build one for learning purpose! Greetings Daniel Edited 2022-04-11 03:24 by Amnesie |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
Definitely not in your application but it is somewhat unusual. Normally ,if you are writing to disk it is because that is important. In your specific application personally I would use two Pico. One would do the monitoring and alarm and would communicate with the second in a non-blocking way e.g. serial. The second would listen to the incoming data and do the less important work. I think this would fit with your engineering approach and is certainly the way many mission critical systems are built with separate autonomous components |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7937 |
As Peter has pointed out, a dual hardware system is *far* safer than a single software application. You can use the two to monitor each other so, for example, the logging device can signal an alarm if the monitoring device fails to provide it with continuous data (or a watchdog pulse) after a startup delay. Likewise the monitoring device will expect an ACK after each data packet sent to the logger and will alarm if it is missing. Some systems would also split the power supplies and monitor them independently to detect possible brownout situations. Two PicoMites is a *really* cheap solution to something like this. :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
Should "On Error" only be removed for the Picos or are all Mites affected? Should we also use two CMM2 in the future? I find all this very ... confusing. I cannot follow this reasoning. ![]() causality ≠correlation ≠coincidence |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4311 |
IMO For the purposes of checking if an MMBasic command fails and reacting to that failure there is nothing wrong with ON ERROR SKIP, or at least nothing wrong since Peter has addressed the insidious bug that @vegipete reported at the beginning of this thread. Like all error handling mechanisms it is open to abuse, and YMMV when writing mission critical or embedded solutions. The whole "should you check all the conditions so X can't fail vs. catching and handling when X does fail" is tantamount to a religious debate and not very helpful when you just want to get something running especially as a hobbyist. For MMBasic checking the conditions in advance appears to be more expensive than dealing with the failure so I lean towards the latter. YMMV Tom Edited 2022-04-11 04:31 by thwill MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7937 |
hehe Would you like to remove it from GWBASIC while you're at it? Peter: I said (and note the qualifier): Why remove it from anything? There's nothing wrong with using ON ERROR constructs, it's just that sometimes there's not really a reason to - things can be handled better. e.g. look for a required file and inform the user if it can't be found, giving them the opportunity to insert the correct SDcard rather than use an ON ERROR IGNORE trap in the FILE OPEN system. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
ON ERROR isn't going to be removed. I just think it is often overused in a lazy way and my polemic was always intended to stimulate discussion. Amnesie has a valid use except that if he really wants a high availability system for the monitoring it would, IMHO, make more sense to offload "vulnerable" processing to a second, very cheap, processor rather than relying on ON ERROR to bail him out when writing to SDcard which is definitely not a high availability device. The CMM2 has never been designed as a process control or monitoring device but the original Micromite and now the PicoMite are/will be used in this way. Going back to the OPs issue, is it appropriate to put an ON ERROR SKIP before every line with a division in it in case there is a divide by zero? Surely it is better to understand your program and put specific code into it to deal with boundary conditions rather than just continuing regardless? Tom: If you want the fix the changes are in MM_Misc.c. OPTION ERROR IGNORE sets OptionErrorSkip to minus-1 so this would work in both the main code and the interrupt int SaveOptionErrorSkip=0; GotAnInterrupt: LocalIndex++; // IRETURN will decrement this if(OptionErrorSkip>0)SaveOptionErrorSkip=OptionErrorSkip; else SaveOptionErrorSkip = 0; void cmd_ireturn(void){ if(InterruptReturn == NULL) error("Not in interrupt"); checkend(cmdline); nextstmt = InterruptReturn; if(LocalIndex) ClearVars(LocalIndex--); // delete any local variables TempMemoryIsChanged = true; // signal that temporary memory should be checked *CurrentInterruptName = 0; // for static vars we are not in an interrupt InterruptReturn = NULL; if(DelayedDrawKeyboard) { DelayedDrawKeyboard = false; DrawKeyboard(1); // the pop-up GUI keyboard should be drawn AFTER the pen down interrupt } if(DelayedDrawFmtBox) { DelayedDrawFmtBox = false; DrawFmtBox(1); // the pop-up GUI keyboard should be drawn AFTER the pen down interrupt } if(SaveOptionErrorSkip>0)OptionErrorSkip=SaveOptionErrorSkip+1; } Edited 2022-04-11 04:43 by matherp |
||||
twofingers![]() Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1593 |
A good decision! (Wiping sweat from my forehead.) Thanks! causality ≠correlation ≠coincidence |
||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 675 |
I love to hear that, and you are absolutley right that a second device for the SD card task is the best solution for maximum safety. Yes I am planning a lot of projects in this way and CNC-milled some cases for this purpose and made a whole new set of PCBs. I LOVE the PICO :) Our laboratory at university got one, too ;) ![]() Edited 2022-04-11 06:23 by Amnesie |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3378 |
Neat case. Glad to see the 2x20 connector. What's it look like inside? PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |