Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Pi-cromite: Next steps
Page 2 of 2 | |||||
Author | Message | ||||
lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3019 |
There is no order implied in the ~nn tags, and none, I think, in Jim's. "~23" can be followed by"~14". The values I replace the tags with are stored in a string array, indexed by the number following "~". The program provides a new value for the string array element when a sensor value changes. In the next html update, the new value is plugged in. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
I am used to update the page on the client side, and request only the changed data from the server. Javascript can be used for lots of nifty templates. I find i have more control over the visual aspects by just building a HTML/CSS file that is static, and then use the server for data only. That way i can easily build a page with tools that are made for it and i don't have to manage a lot of print# statements in basic. Once pages show more then a few numbers and start to get some nice layout and visuals it starts to get very difficult and obscure when you not separate that part out of the basic program. When building html nesting is often something that can go wrong easily. missing a closing tag can really screw up the layout. Building a page with simple tools like for instance https://www.w3schools.com/html/tryit.asp?filename=tryhtml_intro makes it so much faster. Microblocks. Build with logic. |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8597 |
Please find attached 5.3.a26 2017-05-12_195518_mmbasic.zip NB file updated at 19:07 UTC to remove diagnostic print Note "TRANSMIT HTTP 1.1" is changed to "TRANSMIT HTML" This version implements a complete set of routines for handling long strings. Particularly useful for parsing out HTTP requests These are taken from Geoff's long string CFunctions, but because CFunctions are impossible in the Pi-cromite they are included in the firmware. The syntax is pretty much the same as the CFunctions although the way they are called is somewhat different. Geoff's document is attached: 2017-05-12_162403_Long_Strings.pdf and the changes are best understood by my test program. There is one additional routine which allows you to substitute characters into an existing string LONGSTRING REPLACE array%() , newstring$, start-position Note that unlike the CFunctions these calls all use integer arrays to hold the long strings. The calls all check for the arrays being big enough and give an error if any call would exceed the array limits. Dim a%(100) 'enough for 800 character string Dim b%(10) LongString load a%(),16,"1234567890abcdef" Print "chars 4-9 are: ", LGetStr$(a%(),4,6) s$="ABCDEFGHIJKLMNOPQRSTUVWXYZ" LongString append a%(),s$ Print "stringlength now :", LLen(a%()) If LInStr(a%(),"ghij") Then Print "ghij found" Else Print "ghij not found" EndIf Print "convert string to lower case" LongString lcase a%() If LInStr(a%(),"ghij") Then Print "ghij now found" Else Print "ghij now not found" EndIf LongString append a%(),s$ LongString append a%(),s$ LongString append a%(),s$ LongString append a%(),s$ LongString append a%(),s$ LongString append a%(),s$ LongString append a%(),s$ LongString append a%(),s$ LongString append a%(),s$ LongString append a%(),s$ Print "stringlength now :", LLen(a%()) start=1 Do p=LInStr(a%(),"ABC",start) If p Then Print "ABC found at position ",p start=p+1 Loop While p>0 Print "Convert to upper case" LongString ucase a%() p=LInStr(a%(),"ABC",start) If p Then Print "ABC now found at position ",p LongString left b%(),a%(),20 Print "left-most 20 characters of a% are ",LGetStr$(b%(),1,20) LongString right b%(),a%(),20 Print "right-most 20 characters of a% are ",LGetStr$(b%(),1,20) LongString mid b%(),a%(),20,20 Print "chars 20-39 characters of a% are ",LGetStr$(b%(),1,20) Print "Now clear a%" LongString clear a%() Print "a% is now ",LLen(a%()), " characters long" Print "copy b% to a%" LongString copy a%(),b%() If LCompare(a%(),b%())=0 Then Print "Compare :the strings are the same" Print "a% is now ",LLen(a%()), " characters long" LongString concat a%(),b%() Print "a% is now ",LLen(a%()), " characters long" If LCompare(a%(),b%())=1 Then Print "a% now bigger than b%" If LCompare(b%(),a%())=-1 Then Print "b% now smaller than a%" Print "b% is currently ",LGetStr$(b%(),1,30) LongString replace b%(),"hello",5 Print "b% is now ",LGetStr$(b%(),1,30) |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5915 |
I have noticed a few strange events with the random number generator. > list For n = 1 To 20 Print Rnd()*100 Next n > run 1.630068 24.2887 13.7231 80.4176 15.6679 40.0944 12.979 10.8809 99.8924 21.8257 51.2932 83.9111 61.2639 29.6031 75525711 52.4287 49.3582 97.2774 29.2516 77.1357 > > > run 97.94334 74.381 90.3365 98.3595 66.688 49.7258 16.3968 83.0011 88.8948 7.69946 64.9706 24.8044 947.8909 22.9137 70.0619 31.6867 32.8777 23.1428 7.41609 63.3072 > > The first issue is the way that the first printout in the list 'usually' omits the leading space. Not always and once the second line did it as well. The big problem is the occasional number that is way out of range. This happens about every 15-20 time I run the program. I also noticed a repeated sequence but I think it only happens with a mmbasic restart. VK7JH MMedit MMBasic Help |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8597 |
Please find attached 5.3.a27 2017-05-13_104231_mmbasic.zip This uses the time to initialise the random number generator and it also includes three new options on the TRANSMIT command The first is used to tell the browser that it is asking for something we can't serve Transmit NULL This sends the string "HTTP/1.0 404\r\n\r\n" This can be used for responding to an invalid page or a FAVICON request if you don't have an icon The second allows us to send a style sheet Transmit CSS "cssfilename" This sends the css file "cssfilename" if it exists or a NULL response if it doesn't. The third is used for responding to a favicon request Transmit FAVICON This send the icon file favicon.ico if it exists or a NULL response if it doesn't Use of these is demonstrated in the attached demo program. Note the use of the long string handling to simplify the parsing. Dim a%(100) Dim crlf$=Chr$(13)+Chr$(10) Dim q$=Chr$(34) Open "socket,myint,100" As #2 Do Loop Sub myint 'load the request Do While Not Eof(2) LongString append a%(), Input$(10,2) Loop p%=LInStr(a%(),"GET",1) t%=LInStr(a%(),"HTTP",1) s$=LGetStr$(a%(),p%,t%-p%) Print s$ LongString clear a%() ' If Instr(s$,"favicon") Then Transmit FAVICON Else If Instr(s$,"styles") Then Transmit CSS "styles.css" Else Print #2,"<html><head><title>My test</title>"; Print #2,"<link href="+q$+"styles.css"+q$; Print #2," rel="+q$+"stylesheet"+q$+" type="+q$+"text/css"+q$+"></head>"; Print #2,"<body>The body</p>"+Time$+"</body></html>"+crlf$; Transmit HTML EndIf End Sub The simple style sheet I used was body { background-color: powderblue; } saved in the same directory as mmbasic as "styles.css" The favicon I use is the raspberry pie one 2017-05-13_104113_favicon.zip also saved in the same directory as mmbasic Jim: I can't replicate your formatting issue on either a Pi 3 or Pi zero W. It may be some sort of local networking issue. Next steps are to handle other image file types Does anyone want to design a MMBasic favicon? We really ought to have one |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3668 |
You may need to read the RFCs for HTTP, MIME, etc I dimly recall Content- headers (Content-coding, Content-type, etc) and related headers (Accept- etc). There's no doubt example code on the net :) John |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
@Matherp, nice progress. It might be better to use [code] TRANSMIT 404 [/code] Instead of using NULL. There are a lot of codes that are very useful. My suggestion would be that when a number follows the TRANSMIT command it will be a HTTP status code. Otherwise it will be a content-type followed by a optional filename. You would then also be able to send a static html file with [code] TRANSMIT HTML "index.htm" [/code] Same as you do now with a CSS file. Another great option would be to use a variable to contain the filename. Being able to use a filename variable would allow the programmer to extract the filename out of the URL You can then add all other things in a similar way. [code] TRANSMIT JAVASCRIPT "myscripts.js" TRANSMIT JAVASCRIPT jsFilename$ 'filename in a variable. TRANSMIT PNG "tiger.png" TRANSMIT JPG "tiger.jpg" [/code] HTML,JAVASCRIPT,PNG,CSS etc could then be defined constants that stand for a full content-type. If you want to use a specific content-type then it would be nice to use the following [code] TRANSMIT "application/vnd.ms-excel" "mysheet.xls" [/code] It would be impossible to have a keyword for every used content-type (see http://www.iana.org/assignments/media-types/media-types.xhtml for a list) so having the possibility to use a string would allow any content to be send. If sending a css file and favicon works then you already have everything in place to send other content types. Microblocks. Build with logic. |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8597 |
Attached 5.3.a28 2017-05-13_140515_mmbasic.zip Thanks to MicroBlock for the ideas I think I've got something interesting working I've simplified things as follows: Transmit now has just three options TRANSMIT CODE NNN This sends a simple response: "HTTP/1.0 NNN\r\n\r\n" Note the code is always three digits TRANSMIT HTML This constructs a header for an HTML page and sends any data that has been buffered using "PRINT #" to an opened socket. TRANSMIT FILE "filename", "content-type" This constructs a header with the content type specified and the length of the file, sends it and then sends the contents of the file This should now cater for pretty much anything. The example program serves a simple html page with a css sheet, a favicon, and an embedded jpeg image. The full list of content types are detailed in the link in the post from MicroBlocks above. Dim a%(100) Dim crlf$=Chr$(13)+Chr$(10) Dim q$=Chr$(34) Open "socket,myint,100" As #2 Do Loop Sub myint 'get the request Do While Not Eof(2) LongString append a%(), Input$(10,2) Loop p%=LInStr(a%(),"GET",1) t%=LInStr(a%(),"HTTP",1) s$=LGetStr$(a%(),p%,t%-p%) Print s$ LongString clear a%() ' If Instr(s$,"favicon") Then Transmit FILE "favicon.ico","image/vnd.microsoft.icon" Else If Instr(s$,"styles") Then Transmit FILE "styles.css","text/css" Else If Instr(s$,"tiger-3.jpg") Then Transmit file "tiger-3.jpg","image/jpeg" Else Print #2,"<html><head><title>My test</title>"; Print #2,"<link href="+q$+"styles.css"+q$; Print #2," rel="+q$+"stylesheet"+q$+" type="+q$+"text/css"+q$+"></head>"; Print #2,"<body>The body</p>"; Print #2,"<img src="+q$+"tiger-3.jpg"+q$+" alt="+q$+"mypic"+q$+"><p>"; Print #2,Time$+"</body></html>"+crlf$; Transmit HTML EndIf There is one more (hard!) bit of the puzzle to do and this is to take a static HTML file and automatically embed in it variable data. There have been lots of great suggestions for this above. My instinct is to follow MicroBlocks and use {} around the variable name. My intention is only to support simple string variables so that it will be up to the MMBasic programmer to maintain these from the relevant numeric values using STR$ The TRANSMIT HTML command will be extended to support an optional filename and will automatically do the data merge as it sends the file Thoughts? |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
That will work! An automatic replacement of values in {} by their variable content would be indeed the easiest way to manipulate a html. What i often do is created html snippets on the server that the client can insert into the main html document. Having the possibility to read a file (any file?), replace all {variable} instances with values and then send it would be super. On a Windows Server t is easy to just read the whole file in memory and then do all the replaces. But for a smaller system it would be enough to just read it and process it line by line. CR+LF would then be the most obvious delimiter. In HTML CR and LF are skipped so defining a html file with reasonable length lines is very doable. If you are up to it there are a few more things that can make live easier. First: Allow extra headers to be send. This will then give the option to allow cross domain scripting. This header will allow all pages from all domains to request data: [code] Access-Control-Allow-Origin: * [/code] The * means any, you can also allow only certain domains. This will give the possibility to integrate data gathered on the Pi-cromite to be display on any website. Normally the browser will not allow to request data cross domain, this header is like a 'whitelist' of domains that are allowed to. There are many other headers that can be very helpful. Like caching headers and to many to mention. Here is a list: https://msdn.microsoft.com/en-us/library/ms537417(v=vs.85).aspx maybe it could be done by allowing an extra parameter to the TRANSMIT command. [code] Dim HeaderArray(2) HeaderArray(0) = "Access-Control-Allow-Origin: *" HeaderArray(1) = "Cache-Control: max-age=68000" TRANSMIT "data.csv", "text/csv", HeaderArray [/code] Above example allows websites from any domain to request the data. And the data is suggested (by the server) to be cached (on the client) for 68000 seconds. Second. To make parsing easier you could parse the request in the firmware and expose a headers array. This will allow the programmer to quickly iterate through them. The first is important if the data has to be shown or shared with other websites and have more control about what is being sent. The second is a nice to have as it makes parsing simpler. Microblocks. Build with logic. |
||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 1986 |
the idea of {} is useful as a general feature in string manipulation - reminds me of mailmerge templates... |
||||
lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3019 |
Perhaps as an option, if {} encloses a number, that would be an index into a text array containing the value to be inserted. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
Page 2 of 2 |
Print this page |