-
-
No analog output without it, right?
Could be limiting for the project I have in mind... I have a dozen raw 12E boards I bought for $1.99 ea from China for this particular (lightstrip) project. Since each strip -- and there are many -- needs its own MCU, it simply isn't financially practical to do this with the official boards :-(
-
I remember lusting over a TRS-80 back in the 70s as a teen. Didn't actually have my own real computer until college, when I saved and saved and saved and then bought a Commodore 64. Programming in Basic.
Man, those were different days.
Now, look what's out there. I wonder what wonders my own son, now 20, will be marveling at 30 years from now that make this sort of thing look like a Commodore 64 :-)
-
Thanks for the quick feedback, Gordon.
When it arrives, which board version of the current build should I try to flash, and see if it works?
Re: STM dev boards -- thanks for the pointer, I'll check it out. I ended up throwing this in the cart on a whim while I was grabbing a basket of different sensors to play around with. I suppose I could change the order, but at this point I think I'll just go ahead with product. As much as I've become an Espruino fan, it't not the only way to develop for that device, so I have other avenues if it turns out to be too big an effort.
Plenty of other Espruino work going on in my secret project room somewhere down in the basement :-)
-
Ordered one of these to evaluate and play with it. Haoyu provides some (what I've heard, pathetic) development support with code and tools, but I'd like to try Espruino on it:
- Serial RS-232 USART (USART1)
- On-board programming debugging status indicators
- 20-pin ARM JTAG interface
- 8 bit bus interface expansion port
- Varistor for ADC input
- 2 x User LEDs
- Power indicator LED
- 2 x User Keys
- ISP Key
- Reset Key
- 10/100M RJ45 Ethernet
- Stero audio output port
- LCD connector support 16-bit true color, RGB interface. resistance
and capacitance touch screen is not compatible, see here. - MIC input (No welding Microphones)
- Power supply 5V/1A input, 5.2mm(ext. diameter) x 2.1mm (int.
diameter) barrel plug - USB Host port
- USB Client port (micro)
- CR1220 RTC Battery Holder
- RS485 (USART6)
- CAN1
- CAN2
- Micro-SD slot
- Micro USB Debug port(USB to USART1 with CP2102)
- On-board programming USB Client port (micro)
I'm guess the display will be completely dead on Espruino without porting the driver (it seems this display is a full 24-bit device with 8 R, G, and B data lines to send/receive pixel data -- quite different than the FSMC interface to the MiniSTM32 3.2" resistive touch display I've been playing with, and has Espruino support).
While fairly new to the MCU world and Espruino, I'm no slouch when it comes to software development, so I'm not shy about taking on porting Espruino to this system. It has some very attractive features in addition to the display:
Processor: ST STM32F429IGT6, ARM Cortex-M4 Microcontroller, working at 180MHz
- 256 KB SRAM for code and data use
- 1 MB ROM containing boot code and on-chip software drivers
32MB SDRAM
4MB SRAM
8MB NOR
128MB Nand Flash
In addition, the host IO board has a lot of built-in standard connectors, so it would be simple to put this in a project as a very nice human interface.
I know little about the internals of Espruino; not sure if there is support already for all that RAM and secondary storage. If not, is it pretty simple to support it (i.e., change some configuration parameters for the build, rebuild, voila! -- or, have to rewrite all sorts of code all over the place to support the larger address sizes, larger buffers, etc.).
Anyway, just looking for some feedback from the experts. Would any of the M4 versions of Espruino have a good chance of "just working" with a console over the USB or serial connections? I doubt it, but worth asking...
- Serial RS-232 USART (USART1)
-
@allObjects: Yeah, "class" in Javascript is a poor bastard of the real thing. My history is doing a log of Javascript about 10-15 years ago, then none for a decade and in that time doing a lot of Java (Android) up to the present, then getting back on the Javascript bandwagon in the last few weeks as I found and got into Espruino.
So I AM mapping a lot of concepts from Java to Javascript, and learning about the "object model" -- really the prototype inheritance chain.
A lot has happened with JS in that last 10 years... :-)
-
@allObjects: brain ignored this for some reason, must be my advancing age at 54 :-)
Yes, what you say about overwriting prototype above is correct. I tried that as an alternative to what Gordon suggest -- having tried it an found the function in property fillRect inaccessible -- hoping the prototype object was accessible instead (it's not either). Of course, IF that would work, there's the entire problem of shallow vs. deep copy, etc.
If the proto object WAS accessible, I was going to then deal with the copy issue (there are ways to make that copy, as I'm sure you're aware -- you're far more experienced with this stuff than I am :-))
-
One other comment I'll add is I'm certain I'm doing much of this "wrong" in the sense that I'm overbloating the code with flexibility and functionality. I'm new to the MCU world, so am not particularly sensitive to keeping things compact and to the essentials for a small memory footprint.
I plan to do a bunch of optimization after I get this all working, throwing out stuff that really isn't necessary in this environment. Also, as mentioned above, the plan is to make a basket of individual modules that can be loaded as needed for particular UI elements, so not all the code needs to be taking up space if it isn't used.
-
@Wilberforce: Could you elaborate with some more detail? I'm not clear on what you're suggesting.
My intent was to eliminate the extra line of code setting the color before calling the drawing commands, as I need to change colors regularly for animating various widgets, and the Button widget (which I'm working on right now) has 3D effects (looks raised, then pushes in when pressed).
I'm interested in your suggestion -- I just need to understand it :-)
-
I've been satisified so far with the speed of the HY display/MCU combination, and the driver that Gordon leveraged in to run it. It uses FSMC to talk to the board and transfers data at 16 bit words over a parallel I/F, rather than SPI or some other serial interface, so it's quite fast.
Latest progress attached for anyone that wants to play with this. Since this code is in development and evolving, there are some naming changes (unpack565RGB is now unpack16RGB, for example, among other changes), some things have been completely rewritten, etc.
Some new stuff: polarFillPoly function that provides for creating a filled polygon with a set of vertices in polar coordinates (radius, angle), and a specified origin. Makes it simple to draw regular polygons, and circles.
Also a set of duplicated Graphics functions with "2" appended (e.g. fillRect2()) that can be used in place of the standard functions, but allow for the inclusion of a color parameter to set the drawing color.
Plan is to create separate modules for each control so that only the code for the controls being used is loaded into memory via 'require' statements in the code using the GUI.
Anyway, current code -- messy state that it is, not everything working -- attached, for anyone that wants to play around with this current state of progress. I'll be finishing Button, Checkbox, and implementing a RadioButton today.
At U$32, the HY 3.2" display is a very attractive solution for projects that need user interaction... nothing beats a color graphics touchscreen for interacting with a user :-) Hence my interest in developing a GUI library/module. My needs/wants are enough GUI for me to put in the effort, and hopefully having something that others can and will use too.
In the end, having a simple, flexible, easy to use GUI for the HY boards may stimulate some use of them, expanding the use of Espruino, creating more support, etc. I know Gordon et. al. do not get financial support directly when people use these boards, but I'd expect good people to chip in via donate... That's what I do :-)
Plus, developing this code is fun.
-
@allObjects: In a prototype function 'this' will reference the particular instance of an object created with the 'new' keyword -- that's my understanding :-)
@Gordon: Unfortunately, trying to save the function object in a different reference doesn't work -- the native compiled code doesn't expose the symbols, so not even the prototype object referenced by the Graphics.prototype property isn't exposed.
Don't think this can be done without compiling the Graphics "class" with more information -- maybe debug symbols or something.
Don't waste any more time on this guys (other than your own curiosity). It's not important to what I'm doing. Thanks!
-
If I grok what you're suggesting, it won't work because Graphics is native code. There is no Javascript access to the prototype object and its properties (in particular, all the functions like fillRect, for example).
So, I CAN'T do something like:
LCD.oldProto = Graphics.prototype;
Graphics.prototype.fillRect = function() {
if (arguments.length > 4) this.setColor(arguments.slice[-1]);
this.oldProto.fillRect.apply(this,arguments.slice(0,4)); <== this fails -- oldProto is undefined
}
What does work is creating a new "method" with a different name (fillRect2), which works fine since there's no name collision. However, I then have to deliberately code with that name, which makes the code dependent on having my extensions to Graphics loaded.
It's not really a big deal... I'm not working on this for a particular project ATM. Rather, I'm working on developing that GUI module for use on the MiniSTM32 with 3.2" display and touchscreen. Developing this mostly out of interest and fun, plan to share with community and use in the future some time.
I don't have a "real" project for that hardware right now -- just playing.
-
I want to extend the Graphics class and be able to use the same "method" names, but extend them. I'd like to do this by creating my own Graphics2 class that inherits from Graphics.
Problem: How do I create a new Object derived from Graphics2 that's connected to the hardware display, like the built-in LCD object?
This is the code I found in the source that I'm pretty sure is setting up the LCD var:
void jswrap_graphics_init() {
[#ifdef](https://forum.espruino.com/search/?q=%23ifdef) USE_LCD_FSMC
JsVar *parent = jspNewObject("LCD", "Graphics");
if (parent) {
JsVar *parentObj = jsvSkipName(parent);
JsGraphics gfx;
graphicsStructInit(&gfx);
gfx.data.type = JSGRAPHICSTYPE_FSMC;
gfx.graphicsVar = parentObj;
gfx.data.width = 320;
gfx.data.height = 240;
gfx.data.bpp = 16;
lcdInit_FSMC(&gfx);
lcdSetCallbacks_FSMC(&gfx);
graphicsSplash(&gfx);
graphicsSetVar(&gfx);
jsvUnLock2(parentObj, parent);
}
[#endif](https://forum.espruino.com/search/?q=%23endif)
}
Pretty straightforward -- if I was coding in C!
Is there a way to accomplish the same thing in the Javascript interpreter with standard Espruino interfaces/classes, that would be great!
-
Drivers was it... up and running, @Gordon, and blazingly fast! Coding is SOOOOOO much better!!
Turns out I had installed the STM drivers weeks ago, but the COM port installation looked like it was hanging, so I killed it and stayed with the serial. Forgot about that until you mentioned the Quick Reference.
So, plugged it in again, and waited it out this time. Took a long time, but eventually finished successfully and I was able to connect. Thanks!
-
Gordon, here's some more interesting "things": There are two USB connections on the MiniSTM32V; one goes through the Prolific chip and connects to a pins configured as a UART. This is where the console is configured by default, running at 9600 baud.
The other USB connector is connected directly (with buffering) to the STM32, on pins A11/A12/B7 as USB_DM/USB_DP/USB_EN. I've largely ignored this connection to this point, as it was not responsive with the IDE -- I was able to connect with the other "USB" connection.
So... If I could move the console over to the actual real native USB connection, and get awesome speed, that would be ideal. I suspect it's simply a matter of configuring those pins for a native USB connection, then directing the console there -- how do I do that?
BTW sending another U$25 to keep supporting you guys... thanks for everything!
-
Well, not sure about the details of USB... NOT connected directly to the STM32 via the direct USB support. Rather, I'm connected via USB to a Prolific USB->Serial chip on the board that then connects via normal serial to UART function on two pins on the STM32.
This is an HY-STM32V with the 3.2" touchscreen. The serial connection from the USB chip is connected to pins A9/A10 TX/RX.
I tried what you posted above, and got this result:
>Serial.setup(115200)
Uncaught Error: Function "setup" not found!
at line 1 col 8
Serial.setup(115200)
^
>
Reviewing the Serial class documentation, this makes sense -- don't I have to have an actual instance of the Serial class to use it? The documentation talks about pre-instantiated instances Serial1, Serial2, ... and USB.
So, still stuck. And, there's no doubt it's 9600 baud :-)
My main issue here is that at 9600 baud loading the GUI code I'm developing takes a long time, which is painful with edit/test cycles.
-
I can't imagine this hasn't come up before, but I searched and came up empty. So, apologies for what is surely a repeat!
Is there some easy way to set the speed of the console serial port? 115,200 is really nice when working on the ESP8266. Surely the STM32 family can handle that -- and I'd expect much faster.
I'd love to be able to set my Pico to 115,200. I'm guessing I can do it with the right call to Serial.setup() maybe, but I don't know the particulars of setting up the port to talk to the IDE (bits, parity, etc.).
-
A quick followup: Another "NodeMCU" variation that is less expensive and more compact is the Wemos D1:
As cheap as U$4.24 on ebay. Just a hair over the lower prices for raw 12-E boards (U$1.99), but easily usable right away with USB, 3.3V regulator, PCB gpio attachments, reset button, etc.
Only limitation is not all GPIO pins are accessible. Got one, works just like the bigger NodeMCU board (without the LEDs, buttons, and access to a few GPIOs).
-
Embarassing... yes, some code got cut off -- note line 116 ends with '...label:"Butt'! HAHAHA! I assure everyone I did not have an example button with the text "Butt" on the screen :-)
Here's the complete end of the code, the btns array initialization repeated:
var btns=[
{tl:{x:50,y:100},br:{x:170,y:150},RGB:{R:255,G:0,B:0},label:"Button",fontSize:20,onPress:btnPress,onRelease:btnRelease,ID:"btn0"},
{tl:{x:10,y:40},br:{x:130,y:90},RGB:{R:0,G:0,B:0},label:"BL off",fontSize:20,onPress:function(){LCD.bloff();},ID:"btn1"},
{tl:{x:280,y:100},br:{x:320,y:120},RGB:{R:255,G:255,B:0},label:"Button",fontSize:20,onPress:btnPress,onRelease:btnRelease,ID:"btn2"},
{tl:{x:100,y:160},br:{x:220,y:185},RGB:{R:255,G:0,B:255},label:"Button",fontSize:20,onPress:btnPress,onRelease:btnRelease,ID:"btn3"}
];
btns.forEach(function(c){a=new Button(c);});
Buttons are created in line 8 above. Since this was simply code to get some buttons on the screen to test the GUI code, I'm not saving the references to the 4 buttons anywhere. In a real app I'd keep those references when necessary.
I agree completely that our two approaches are really (stripped of minor differences) fundamentally the same. However, ignoring performance considerations (:-)) leaves me more flexibility to implement a more convenient OO model approach. Also makes the code easier to understand (that is, code using the GUI).
There's good reasons for both approaches... Ease-of-use OO-biased design where performance isn't critical (things like footprint, or where there is a heavy on-going CPU load for the application, so minimizing UI processing overhead is really needed). Performance-oriented, efficient running code where CPU cycles and RAM are precious.
Alternatively, for applications like a distributed WS2812B light strip controller, performance isn't an issue at all -- that's basically my case. I'm implementing the controller on a HY-MiniSTM32V board with touchscreen display, then each strip has its own dedicated ESP8266-12E running Espruino, everything connected over wifi on my home network.
So, for me, simplicity in writing the controller code (after the effort of creating the GUI library!) is the driving value proposition.
Is there a screencap function for displays? Otherwise, I'll have to shoot a picture and post it.
-
That's very nice work! Did you take it any further than the buttons and checkboxes?
I'm taking a little different approach with object classes, so the UI elements are easily accessed and can be modified after creation. I haven't examined your code closely (and will), so there may be benefit in continuing this project...
-
Forgot to mention there are some helper function extensions to the Graphics class in there too, dealing with 24 and 16 bit packed RGB triples. Feel free to add these to the Graphics class in the future if want to, Gordon :-) :-)
The 565 and 888 RGB packing/unpacking functions are particularly handy.
-
I may be reinventing the wheel here, but I couldn't find any basic GUI elements for touchscreen devices like the HY-MiniSTM32V board I'm playing with. So, I started writing a simple, very basic GUI library.
Right now, all I've done is create a pretty functional Button class, and only rectangular buttons. What you can do at the moment is place a button on the screen specifying location/size, color, and callbacks for press and release. The button will be drawn with the specified color, and the border and the button text drawn in inverse-color.
When pressed, the button highlights by doing color invert (like a film negative) while pressed, calls the pressed callback, then redraws in its original state when released, and the released callback is called. Both callbacks are optional.
Whole point is to easily draw buttons on a touchscreen that can then be used to control things.
Code follows. As this file stands, it creates 4 demo buttons on the screen when loaded, one of which is labeled "BL off" which turns the backlight (on the HY-MiniSTM32V) off.
echo(0);
ts=require("Touchscreen");
function unpack565RGB(rgb) {
return {
R : (rgb & 0b1111100000000000) >> 8,
G : (rgb & 0b11111100000) >> 3,
B : (rgb & 0b11111) << 3
};
}
function unpack888RGB(rgb) {
return {
R : (rgb & 0xff0000) >> 16,
G : (rgb & 0xff00) >> 8,
B : (rgb & 0xff)
};
}
Graphics.prototype.getRGB = function() {
return unpack565RGB(this.getColor());
};
Graphics.prototype.setRGB = function() {
if (arguments.length>1) c={R:arguments[0],G:arguments[1],B:arguments[2]};
else c=arguments[0];
this.setColor(c.R/255.0, c.G/255.0, c.B/255.0);
};
Graphics.prototype.getBgRGB = function() {
return unpack555RGB(this.getBgColor());
};
Graphics.prototype.setBgRGB = function(r,g,b) {
this.setBgColor(r/255.0, g/255.0, b/255.0);
};
var ON=true;
var OFF=false;
LCD.bl=function() {
if (arguments.length===0) return digitalRead(B5);
if (!arguments[0]) digitalWrite(B5,0);
else digitalWrite(B5,1);
};
LCD.blon=function() {LCD.bl(ON);};
LCD.bloff=function() {LCD.bl(OFF);};
var buttons=[];
function Button(b) {
this.tl=b.tl;
this.br=b.br;
if (this.tl.x>this.br.x) this.tl.x=[this.br.x,this.br.x=this.tl.x][0];
if (this.tl.y>this.br.y) this.tl.y=[this.br.y,this.br.y=this.tl.y][0];
this.w=this.br.x-this.tl.x;
this.h=this.br.y-this.tl.y;
this.RGB=b.RGB;
this.inverseRGB={R:255-this.RGB.R,G:255-this.RGB.G,B:255-this.RGB.B};
this.label=b.label;
this.ID=b.ID;
if (b.hasOwnProperty("onPress")) this.onPress=b.onPress;
else this.onPress=undefined;
if (b.hasOwnProperty("onRelease")) this.onRelease=b.onRelease;
else this.onRelease=undefined;
this.fontSize=Math.min(this.h-4,b.fontSize);
LCD.setFontVector(this.fontSize);
while (LCD.stringWidth(this.label)>this.w-4) LCD.setFontVector(--this.fontSize);
this.fontX=(this.tl.x+this.br.x-LCD.stringWidth(this.label))/2;
this.fontY=(this.tl.y+this.br.y-this.fontSize)/2;
buttons.push(this);
this.draw(this.RGB);
}
Button.prototype.draw=function(c) {
inverse={R:255-c.R,G:255-c.G,B:255-c.B};
LCD.setRGB(c);
LCD.fillRect(this.tl.x,this.tl.y,this.br.x,this.br.y);
LCD.setRGB(inverse);
LCD.drawRect(this.tl.x,this.tl.y,this.br.x,this.br.y);
LCD.setFontVector(this.fontSize);
LCD.drawString(this.label,this.fontX,this.fontY);
};
Button.prototype.hit=function(x,y) {
if ((x<=this.br.x) && (x>=this.tl.x) && (y<=this.br.y) && (y>=this.tl.y)) return true;
else return false;
};
var curBtn;
function doButtons(state,x,y) {
if (!curBtn) {
for (var i=buttons.length-1; i>=0; i--) if (buttons[i].hit(x,y)) {
curBtn=buttons[i];
curBtn.draw(curBtn.inverseRGB);
if (curBtn.onPress) curBtn.onPress(x,y);
}
}
else {
if (state) return;
curBtn.draw(curBtn.RGB);
if (curBtn.onRelease) curBtn.onRelease(x,y);
curBtn=undefined;
}
}
function onTouch(x,y) {doButtons(x?true:false,LCD.getWidth()-x,y);}
ts.connect(onTouch);
function btnPress() {console.log(this.ID+" pressed");}
function btnRelease() {console.log(this.ID+" released");}
var btns=[
{tl:{x:50,y:100},br:{x:170,y:150},RGB:{R:255,G:0,B:0},label:"Button",fontSize:20,onPress:btnPress,onRelease:btnRelease,ID:"btn0"},
{tl:{x:10,y:40},br:{x:130,y:90},RGB:{R:0,G:0,B:0},label:"BL off",fontSize:20,onPress:function(){LCD.bloff();},ID:"btn1"},
{tl:{x:280,y:100},br:{x:320,y:120},RGB:{R:255,G:255,B:0},label:"Button",fontSize:20,onPress:btnPress,onRelease:btnRelease,ID:"btn2"},
{tl:{x:100,y:160},br:{x:220,y:185},RGB:{R:255,G:0,B:255},label:"Butt
-
-
Is the SDIO interface to the SD card implemented? All I've been able to find on the site is discussion/code/modules for the SPI interface to an SD card.
If it is implemented, how do I access it? I while I can determine the pins on the STM32 the SDIO card reader is connected to, I don't know what Espruino calls to make (or module to load, if any) to set up with those pins and access the card.
Well, what what got me curious was this text from this page:
It sure seems to imply there is hardware support for PWM -- after all, why would there be the odd 10-bit PW setting. I doubt when porting the Arduino code to the ESP8266 someone decided to expand the software PWM pulse width resolution to 10 bits. I didn't look any further, but will dig a bit more.
In any case it works on the competition -- we need to get it working for Espruino. After all, Javascript is soooooo much better a platform...