chipKIT® Development Platform

Inspired by Arduino™

New guy checking in... :)

Created Fri, 23 Aug 2013 01:39:35 +0000 by unexpectedly


unexpectedly

Fri, 23 Aug 2013 01:39:35 +0000

Hi!

I just discovered chipKIT and am kinda kicking myself for not finding it sooner!!! This is my current project and my uC32 and proto board arrive tomorrow... I'm really being held back by the limited SRAM and I'm excited to bask in the glory that is the uC32's 32K!!

:geek: Chris


majenko

Fri, 23 Aug 2013 21:22:23 +0000

Welcome to the world of real microcontrollers ;)

I feel like we should be throwing you a Bah Mitzvah or something as you're coming of age :P

You'll find that with the extra SRAM you can breathe a sigh of relief and not worry so much about what you are squeezing in. The extra flash is nice as well. Still... 32K? Pah... I'm finding 128K of the '695 and '795 chips is too little these days :P


unexpectedly

Sun, 25 Aug 2013 07:44:43 +0000

Oooo! Which boards come with that much RAM? Wow! :D

BTW, any quickie guides for porting Arduino SPI AVR code to chipKIT-speak? ;)


majenko

Sun, 25 Aug 2013 09:54:58 +0000

Any of the boards with a pic32mx695f512 or pic32mx795f512 chip - so the MAX32, some of the Fubarino boards, etc.

PIC32 chips are considerably more complex than the 8-bit AVR chips. If you want to do any register level stuff then you will need to understand how the chips work. The best resource for that is the "PIC32 Family Reference Manual" (or FRM) which is split into a large number of sections, each one going into quite a lot of detail about different aspects of the chip and the builtin peripherals.

Go to: [url]http://www.microchip.com/TechDoc.aspx?type=ReferenceManuals[/url] and type "PIC32 Family Reference Manual" into the entry box at the top of the table.

Also the data sheet for the specific chip on your board will give you more specific detail about the exact peripherals in it.

Some differences to note between Arduino and chipKIT:

  1. The chipKIT software is based on Arduino 0023, so libraries must include <WProgram.h> not <Arduino.h>, but 1.0.x compatibility is in the works.
  2. The SPI library is somewhat lacking - it only allows one SPI port to be used. Use the DSPI library instead, which allows access to all the SPI ports.
  3. The same goes for I2C - use the DTWI library instead.
  4. The PIC32 is faster, and as a result the serial communication is more accurate (timing wise). You'll find you won't be able to communicate well between an Arduino and a chipKIT at more than 115200 baud as the Arduino can't get the baud rate to be as accurate as it needs to.
  5. Libraries written specifically for the Arduino (i.e., do register access, or use Arduino specific code) will not work on the chipKIT. You will have to either find an alternative library or write a more portable one.

For writing pic32 SPI specific register level code, you should start with the SPI portion of the FRM:

[url]http://ww1.microchip.com/downloads/en/DeviceDoc/61106G.pdf[/url]

Or just use the DSPI library.

That's all that springs to mind off the top of my head.


unexpectedly

Mon, 26 Aug 2013 07:31:50 +0000

Thanks for your great reply! I'm sure it'll get me going in the correct direction. It looks like there isn't too much AVR-specific stuff in the GFX code, so it might not be "that hard" :lol: :roll: :?

Thankfully, I don't make them talk to each other... but I have to wonder if the PIC32 would have been able to handle this: (Test Bench for Measuring Timing Belt Lengths) all on its own! I got real close with the Arduino using a D-FF to gate the "quarter" quadrature signals. If you're at all interested about my comment there, read down to at least the 5th post where I talk about needing a quadrature counter IC :P. And this write up is slightly more practical and explains things a bit more real-world-like.

It will actually take some restraint for me to NOT go back and try that test bench with my spare UNO32 when I figure out how to get the SPI talking to the 1.8" TFT that I am so in love with. Seriously, I love that shield. Joystick AND graphics? Win.

:D Chris


majenko

Mon, 26 Aug 2013 08:25:01 +0000

Sounds like a dsPIC33F series chip would be a better choice. Built-in hardware quadrature encoder interface. Can't be programmed with anything Arduinoesque yet though, as there's no C++ compiler available for it. Should be programmable with Firewing though, with a little bit of tweaking...


unexpectedly

Mon, 26 Aug 2013 09:11:46 +0000

Yeah... that's total greek to me... I already am having to work getting my uc32 to talk to the graphics shield. I don't even want to think about all the new language you just sent my way.

HOW EFFFING MANY new arduino-like microcontroller products exist?!??! Good grief! In university (last century) there was only one < $1000 embedded and easy to code platform in existence! Now there are so many and with so many features, I can't even grasp how I would fully harness them!

... and I still have a belief the chipKIT uno32 could watch the quadrature signals directly and keep up. Especially if I hook up the D flip flop circuit to gate the signals to up/down pulses every 4th micron.


majenko

Mon, 26 Aug 2013 09:23:51 +0000

YHOW EFFFING MANY new arduino-like microcontroller products exist?!??! Good grief! In university (last century) there was only one < $1000 embedded and easy to code platform in existence! Now there are so many and with so many features, I can't even grasp how I would fully harness them!

Tell me about it - I keep finding new ones I need to support in UECIDE. I came across an entire new family just the other day - the Maple system. Seems to be lagging somewhat behind on software though.


unexpectedly

Tue, 27 Aug 2013 04:03:48 +0000

Wow, chipKIT is about to run me off:

http://chipkit.org/forum/viewtopic.php?f=13&t=2521 http://www.chipkit.org/forum/viewtopic.php?f=7&t=653

Seriously...

I'm quite saddened at the total lack of preparation chipKIT is for actual use. Arduino might be lego toys for kids, but when toys can actually get work done?!?!

There's only so much time I can waste on something before it simply is not acceptable in a production environment.

SPI should have been a simple "slam dunk", to use an American idiom... If chipKIT cannot ever do something this simple, how am I to go on with confidence? I'm to the point I can bit-bang SPI in AVR... if chipKIT is so advanced, yet doesn't even have a working SPI code example, what's the point?

:P

I'm hoping tomorrow brings me something more positive. I have completed all of the 3D prints for this test bench, so I don't have any more excuses to "stall" while I try and figure out the chipKIT.


majenko

Tue, 27 Aug 2013 09:40:10 +0000

That thread is like 2 or so years old. Things have moved on somewhat since then.

Like I mentioned earlier - don't use SPI, use DSPI:

#include &lt;DSPI.h&gt;

DSPI0 SPI;
DSPI1 SecondSPI;
//...
SPI.transfer(0x65);
byte data = SecondSPI.transfer(0xFF);

And there you have two working independent hardware SPI channels.


unexpectedly

Tue, 27 Aug 2013 17:57:50 +0000

Right but DSPI2 is the port which works with the Arduino pins 10~13, right? Or is "second DSPI" actually DSPI1 ... and then DSPI2 and 3 aren't implemented (and thus DSPI2 won't compile"?


unexpectedly

Tue, 27 Aug 2013 18:33:01 +0000

OK, so here's the plan...

  1. In Arduino-land, with Arduinos (meaning with a shield to prove something works), I'm going to try and strip out all references to Adafruit_ in the classes and names of the two libraries I'm deriving from working.

  2. Next, find and start removing the AVR program space code.

  3. Work on making their inline AVR SPI hardware commands generic to either Arduino SPI functions or one SPI function internal to the class.

  4. Now, get it to compile in chipKIT... which means stripping out all references to uint8_t ... which I will try to do in both chipKIT and Arduino-land (since in there, I can still prove the code working on a shield).

  5. Try to get it working on all chipKIT hardware...

I'm hoping that steps 1~4 will go easier than my mad drunken scramble last night just trying to get the libs compiling. :roll:


majenko

Tue, 27 Aug 2013 18:48:43 +0000

Heh. Good luck.

You have to remember that an Arduino is like driving an automatic saloon car, and the chipKIT is like driving a 4WD landrover. On the Arduino you have a stop pedal and a go pedal, and you just point it in the direction you want it to go. But it can't get over the rough bits. But the landrover has two gear sticks and about 20 gears, but once you have got it in the right gear it'll climb the side of a mountain no trouble ;)


unexpectedly

Wed, 28 Aug 2013 01:16:05 +0000

[attachment=0]tft_on_mega.jpg[/attachment] I've learned a lot today -- and no wonder I was so confused!!

Some observations: 1» 1.8" TFT shield uses SPI and also two other digital control inputs besides the SS/CS (slave select / chip select) used in the SPI. I didn't realize people would use SPI and still require more control signals. 2» New data line is RS (not RST or reset) and is often referred to on the internet as DC or RS. RS meaning register select, DC for data command or data control. Bring RS low to tell the TFT a command or instruction is what's coming on MOSI line. Once I got this, things progressed quickly. 3» RST is a reset pin. My problem here was that it is ignored with a -1 as often as it is implemented. (So why bother?) 4» digitalWrite() in Arduino is so slow that Adafruit had to use direct port addressing to set the combination of SS and RS required to run the TFT. Thankfully, I have some experience mucking about with AVR PORTs, so I replaced as many of these as possible with the applicable digitalWrite(RS, HIGH), etc, as would still compile and run on the Mega. 5» PGM space is used rampantly so that the code will run on an UNO. I started this conversion on an UNO and almost immediately, it lost its mind. So I bent the SPI pins over and got out the Seeeduino Mega (pictured above) and got back to work. 4 pin header with wires is for Mega's hardware SPI. The loop() repeats a "Free memory" display and those lines of code. I probably should test lines or something, but at this point, I need something/anything to work in chipKIT before I go sussing out all the functionality.

I think it's time to copy these folders over to mpide and get to work...


unexpectedly

Wed, 28 Aug 2013 06:11:36 +0000

YES!! Got it working in chipKIT!

Dumb question: is chipKIT supposed to restart upon upload like Arduino does? ... mine didn't. Not sure if it's because the upload restart happened too quickly for the TFT to init or not.

More observations: » Initially I thought DSPI library didn't work, so I developed on SPI examples. I eventually noticed the LED for pin 13 blinking appropriately for what my loop() was doing... so I hit reset and it started working!!! » I ended up removing ALL DELAYS from Arduino-land! And also running SPI at the fastest speed (40MHz?). » Initially, with the SPI clock divider at 64 and all the delays, the code was slower than Arduino communicating with hardware SPI to the TFT shield. Now? It is obviously and appreciably faster. » Attached zip archive has both my DSPI and SPI examples. The current ST7735 library is the DSPI copy and is more recent than the SPI example. In the SPI version, I didn't remove any and all references to delay. » When hitting RESET button on the shield, the sketch gets into loop() in approx 3 seconds. » When powering up the chipKIT by plugging in the USB, the sketch gets into loop() in 6 or 7 seconds.

NOTICE: I did not perform complete and total tests of every feature and nuance of the code. I got it to print my text! All the Adafruit functions should work, given how everything is coded and structured...


majenko

Wed, 28 Aug 2013 09:55:41 +0000

On the Arduino's SPI you set a clock divider (F_OSC / x where x is 2, 4, 8, etc). On the chipKIT you set an actual speed, not a divider.

/* ------------------------------------------------------------ */
/***    DSPI::setSpeed
**
**  Parameters:
**      spd     - clock speed to set in HZ
**
**  Return Value:
**      none
**
**  Errors:
**      none
**
**  Description:
**      This sets the SPI clock speed to the highest supported
**      frequency that doesn't exceed the requested value. It computes
**      the appropriate value to load into the SPI baud register
**      based on requested clock speed and peripheral bus frequency.
*/

So for a 1MHz SPI bus you use

mySPI.setSpeed(1000000LU);

unexpectedly

Wed, 28 Aug 2013 21:57:24 +0000

I tried DSPI more today and I simply cannot get it working. The default SPI library works. I'm kinda over futzing with this all, so before I go too mad at chipKIT, I'm moving forward with my project using SPI.

Oh, and also, since I'm trying to help Adafruit sell their shields to chipKIT people, I tried the code on my Uno32 and it doesn't work. I started a new thread about that. I really had high hopes for chipKIT but it definitely is not something I would consider ready, fun, solid, or to be relied upon.

Reviewing the posts about SPI, I was really caught off guard by one of this forum's exceptionally snarky and elitist RTFM posts. What makes it worse is that I looked for and Googled for and still couldn't find the reference the guy quoted from and talked down to the OP for not having already read.

Attached is latest version of the ST7735 code, which works for me on my uC32 and not at all for my Uno32.


majenko

Wed, 28 Aug 2013 22:22:47 +0000

Unfortunately I don't know the differences between the uC32 and the Uno32, and I don't have a TFT shield to experiment with (or not yet - I just ordered one, so that aspect of your plan is obviously working ;) ). However, I would suggest investigating the ability to define which SPI channel to use (by passing a pointer to a DSPI instance?) so you can choose which SPI port to have it running from.


unexpectedly

Thu, 29 Aug 2013 00:44:35 +0000

Oh yaaay!!! I really love that shield.

Right... but... DSPI is in the "doesn't work" category for me. DSPI0 is supposed to the the normal pins. SPI just worked.

My current fun is trying to convince the uC32 to perform I2C. The working code lifted from my project of course doesn't work. Then I see this comment in one of the examples:

// From the exmaple SFRRanger_reader.pde ...
	// transmit to device #112 (0x70)
	// the address specified in the datasheet is 224 (0xE0)
	// but i2c adressing uses the high 7 bits so it's 112

Ummmm, the I2C address is 0xE0 but the uC32 doesn't do that so I perform magic on the number...? :? :shock: :roll: :x ... and finally :lol: at myself for my stupidity again. Stupid for not just making the I2C SRAM work on the Arduino and being already done...

Ok, so 224 is 1110 0000 112 is 0111 0000

They bit shifted it right? I've got the o'scope out... using 2.2k pull ups. Well on with the next fight. (Plea for help posted)


unexpectedly

Fri, 30 Aug 2013 05:33:41 +0000

So today (Thursday, the 29th) when a shiney new GHI FEZ Cebruino Bee showed up, I started working on that. 10+ hours later, I can't even get it to blink. So whatever grade I give chipKIT, it is not a failing grade ... and the GHI FEZ crap gets the F.

They're trying to help but honestly, their people haven't sorted out all of the MSVC and .NET crap needed to get their own products running. On a whim, I went to the Netduino page and tried their process for installing the development via MSVC 2010 and I could at least SEE their stuff showing up. So if a person is reading this wanting more than an Arduino and is scared off by my account of the chipKIT, DO NOT ON YOUR LIFE get the GHI Electronics FEZ products. Go directly to Netduino. They seem far better sorted out.

My Netduino 2 shows up Monday...


unexpectedly

Fri, 30 Aug 2013 10:14:19 +0000

This is legendary. If my expectation that something Arduino-compatible should be able to perform I2C out-of-box ... How about not being able to run an LED BLINK without first having to perform a firmware upgrade?

Are my expectations really that far out of line with reality? :roll:

Radio Shack website says that the store on my way to work has a Netduino in stock... if that can run an LED blink without secret firmware updates or special dances to perform, I'm going to take that GHI Electronics FEZ piece of .... to the desert and shoot it with my .45! :shock: :evil:

If something was actually wrong with the board, that'd be ok. But to knowingly ship a board that needs a firmware update?! At least put a sticker over the usb port saying "Doesn't work until you do a firmware update". At which point, I probably would have called GHI and asked why they couldn't be arsed. They just better not answer any calls from the 619 area code tomorrow. Er, later today.


unexpectedly

Fri, 30 Aug 2013 10:22:47 +0000

Unfortunately I don't know the differences between the uC32 and the Uno32, and I don't have a TFT shield to experiment with (or not yet - I just ordered one, so that aspect of your plan is obviously working ;) )

If you private message me your address, I'll post you my Uno32 so you could try and make TFT work on it. Heck, if you already HAVE a Uno32, then I'll post you mt uC32! Then you must really make TFT work on Uno32, as that's what I will still have!!

Cheers, Chris


majenko

Fri, 30 Aug 2013 10:44:33 +0000

I have an Uno32, and as far as I can tell the uC32 is the same board but with a slightly more roomy chip. (320F128 vs 340F512 - same pinout, double the RAM).

I already have a TFT on its way to me (adafruit dispatched it yesterday), so I will be able to get the two working together.

I have quite a collection of boards nowadays...

  • chipKIT Uno32
  • Fubarino SD
  • Arduino UNO R2 x2
  • Arduino Leonardo
  • Firewing
  • Firewing R2 (Beta)
  • Launchpad
  • Stellarpad
  • Microstick II
  • DE0 Nano ... and various I have made myself.

I shall get my sledgehammer out and "adjust" your TFT library so it works on as many of those as is applicable (The DE0 Nano, being an FPGA, wouldn't run the library without first programming it to be a PIC32 ;) and the firewings are programmed in BASIC. )


unexpectedly

Sat, 31 Aug 2013 07:49:50 +0000

Yaaay! Well, I think what I've got is as de-AVR'd as one is going to get.

I've been mucking about in .NET-land for a while. I'm thinking the chipKIT might be the better way to go. Of course, someone implemented a total class for the DS1307 RTC in .NET-land. But since .NET already has I2C handled, that's not really the problem. Why oh why doesn't chipKIT's wire library work? That sucks.

The real problem I have with .NET is the miserable tool chain. What I didn't realize was that there is this "CLR" thing that lives on the embedded target. It is essentially yet another compiler layer. .NET takes multiple languages (C#, J#, and VB) and creates a common language that the board manufacturer then makes firmware which then makes the common language work on the board.

Sort of like java, but without too much of the misery. I say this because I hate java and if .NET relied upon java, I wouldn't even try it. I've been sworn off of java by so much hype and failed expectations already. If only I'd been 19 when it came out...

So, dang it. Maybe I'll revisit I2C on the chipKIT this weekend. It's really freakin hot outside and my house has AC. Sadly, all my chipKIT boards are at work. Thankfully, the tool chain works for the chipKIT both at home and at work :P And there are several air conditioned bars between work and home... :lol:


MarioV

Sat, 31 Aug 2013 09:10:48 +0000

...i2c works on the uno32 without problems! its a little bit more tricky on the fubarinosd, as described here:

http://www.chipkit.org/forum/viewtopic.php?f=7&t=2095

im using the fubarinosd with multiple i2c-ports without any problems! spi & serial works in the same application at the same time...


majenko

Sat, 31 Aug 2013 09:38:39 +0000

The real problem I have with .NET is the miserable tool chain. What I didn't realize was that there is this "CLR" thing that lives on the embedded target. It is essentially yet another compiler layer. .NET takes multiple languages (C#, J#, and VB) and creates a common language that the board manufacturer then makes firmware which then makes the common language work on the board.

Yes, .NET is Microsoft's implementation of Mono. (Or Mono is the open source implementation of .NET?)

Sort of like java, but without too much of the misery. I say this because I hate java and if .NET relied upon java, I wouldn't even try it. I've been sworn off of java by so much hype and failed expectations already. If only I'd been 19 when it came out...

Java isn't that bad as a language. The structure us actually quite nice. I have had to learn it for working on UECIDE, and have actually come to quite like some aspects of it. What I don't like is how it has allowed complete idiots without even half a clue to write complex programs. As a result a there is a huge amount of junk around written in Java, which gives it a bad press. The whole VM thing I'm not to hot on though. It would have been better to have a common language and API that compiled into native code for the platform. Yes, it makes development a little longer as you have to compile for different targets, but at least a 5K java program wouldn't need a 200MB VM to get it to run...

So, dang it. Maybe I'll revisit I2C on the chipKIT this weekend. It's really freakin hot outside and my house has AC. Sadly, all my chipKIT boards are at work. Thankfully, the tool chain works for the chipKIT both at home and at work :P And there are several air conditioned bars between work and home... :lol:

Heh. Wire.h does work, I don't see what you're doing wrong. The only thing you have to remember is that it's Arduino 0023 not Arduino 1.0.x, so you use Wire.send() instead of Wire.write(), and Wire.receive() instead of Wire.read(). At least until the work on making everything 1.0.x compatible is completed. When my DS1306 chip arrives I'll prove it to you :P


unexpectedly

Sat, 31 Aug 2013 23:23:48 +0000

The only thing you have to remember is that it's Arduino 0023 not Arduino 1.0.x, so you use Wire.send() instead of Wire.write(), and Wire.receive() instead of Wire.read(). At least until the work on making everything 1.0.x compatible is completed. When my DS1306 chip arrives I'll prove it to you :P

Yes and I tried that. No dice. I do recall that someone mentioned "changed to Wire.h" moving to 1.0. So I'll look into porting that over. What's really scaring me away from MSVC is my total inability to include others' code. It's a completely different process than knowing where the files are and just including them.

Plus rebooting the target takes forever. And uploading often doesn't work and you've got to unplug and replug the usb connector. So I've flopped back and think if I had just done wire.h for chipKIT in the first place... :P


majenko

Sat, 31 Aug 2013 23:44:56 +0000

Plus rebooting the target takes forever. And uploading often doesn't work and you've got to unplug and replug the usb connector. So I've flopped back and think if I had just done wire.h for chipKIT in the first place... :P

Of course it takes ages to boot - it has to boot Windows ;) And if it doesn't work, turn it off and on again - Did I say Windows?

I don't trust Microsoft on my desktop - why should I trust them in an industrial machine that could slice someone into little tiny chunks if it went wrong?

Oh, and by the way - one of my home grown boards running on the '695H chip is slightly overclocked... It's running happily at 120MHz... Not bad for an 80MHz chip...


unexpectedly

Mon, 02 Sep 2013 02:05:33 +0000

50% overclock, that's nice!

BTW, I'm porting that guy's AVR Menu class now. https://github.com/DynamicPerception/OMLibraries/tree/master/OMMenuMgr

This application I'm building has enough nuances that it's finally excuse to start using a class. My last app had a MUGE menu() function to handle what happened when keys are pressed, which led to handling what's going on in there blah blah. :P


unexpectedly

Mon, 02 Sep 2013 05:32:42 +0000

Stupid AVR making people comes up with schemes to get things go into PROGMEM. I'm pretty sure that's the current bane of my existence. :lol:

So, the attached zip has the files that created the pics...

I initialize and evoke the menu stuff and it all seems OK: [attachment=1]pressformenu.jpg[/attachment]

The A0 - A3 debug code is for a couple reasons...

  1. The joystick's resistor network comes in on A3, so I needed to tweak the values when declaring the menu class and object
  2. I have sensors that I'll put on A1 and A2, so I wanted to see their values.
  3. A0? Just to make sure I didn't solder the wires on the connectors wrong.

So the menu stuff wants a callback function to display to the UI once you push a button...

uiDraw(char* p_text, int p_row, int p_col, int len)

This function in the main program is getting called because I added the debug output to show the 1st 10 characters of a string starting at p_text: [attachment=0]menugarbled.jpg[/attachment]

When the author created this library, all of the memory structure was put into PROGMEM. So I had to strip out a lot of AVR code. Worse, to make all that work, the labels are put into typdef structs and #defines so it would compile. Pretty much the Libraries\OMMenuMgr code needs to be moved from structs and defines to proper c++ classes. I really suck at the OOP. (but good at the OPP - bad joke).

Yaay, progress.


unexpectedly

Wed, 04 Sep 2013 06:38:44 +0000

Made the joystick work and realized v1.01 didn't have that, so I made new version and updated my TFT Shield thread, where I will "maintain" my code. :lol:


unexpectedly

Fri, 06 Sep 2013 06:24:53 +0000

Since majenko is probably the only one that's reading this, I should probably just get his/your email address.

Anyhow, a general vent/rant: There are no menu classes. Nothing out there that is a generic abstract combination of input, menus, and actions.

I'm about to give up and never try OOP menuing again. No wonder cranky old C coding bastards hate java and OOP!! It's really tough. I'm going to give it one more go in my favorite environment: command line php. If I can't build an OOP menu manager there, I'm not going to be able to it anywhere.

And to anyone who has coded menus in windows, qt, java, or any other framework and think it's easy, let's see an abstracted class. All those frameworks take care of these details behind the scenes.

It might well be easier to implement a terminal frame buffer for the TFT and get ncurses working!!!


majenko

Fri, 06 Sep 2013 09:31:31 +0000

TBH I have never done a menu using OOP. IMHO there is no need for a menu to be OOP at all, and no benefit can be gained from it. I can see no situations where you'd be wanting to add/remove menu entries on the fly at runtime. Changing the display name of an entry, yes, for example to display the current setting in with the name, or change an on to an off entry. But adding / removing them? Nah.

Keep it static I say.


unexpectedly

Fri, 13 Sep 2013 08:28:32 +0000

Hey Majenko,

Did I read that just above you said not to bother with OOP menu? :lol:

Hey - actual question: what should I do about getting the serial thermal printer working? Convert Adafruit_Thermal?

I've got it hooked up to pins 2 and 3 right now, but I could connect them to digital 0 and 1 to use UART1 on the uC32. I've got like zero experience in this realm (wow, surprise) but after the pain and suffering making the SPI TFT work, it shouldn't suck too hard.

So a couple questions, if you could please lend your thoughts:

  1. Is there a software serial implementation for chipKIT?
  2. Is the proper thing to do is "just put the printer on 0 & 1"?
  3. If yes to #2, is there any trickerey needed to subsequently update the code in the uC32? I ask because on this Arduino project, I need to stop using D0-7 as a PORT in order to upload new code. Something about the IC being connected pisses the whole thing off, and unless I use the menu option I created to turn off the PORT, I need to take the IC out of the socket and reset lots of times to get new code into the Arduino.
  4. And if yes to #3, what do I need to do?

Looks like I'll be trying to figure out how to do serial tomorrow and start porting that Ada_Thermal library to work for us, defaulted to pins 0:1..................

:D Chris


majenko

Fri, 13 Sep 2013 08:57:50 +0000

Up until now I hadn't bothered with OOP for a menu. Things are changing though as I learn more about polymorphism in C++ (up to now I'd only really used it in Java).

Porting the adafruit library should be pretty straight forward, as it's just serial. There is a SoftwareSerial implementation in chipKIT by default, though I haven't actually used it. I haven't used bitbanged serial since my first PIC16F84A chip back when I was just starting out. These PIC32 chips, you see, have multiple hardware serial ports.

UART port 2: Asynchronous serial port. Pin 39 (RX), Pin 40 (TX). This uses UART2 (U2RX, U2TX) on the PIC32 microcontroller.

So just use those pins and reference Serial1 instead of Serial.

You could pass the serial device to the class in the same way I do the DSPI object in ST7735, so you can select which port to use. You can look at ICSC for an example of how I do it with Serial, and also handling the USBSerial option of some boards (not actually of any use for serial printing, but it's there for you to see anyway - you could adapt that method for SoftwareSerial instead). Since I have got to grips with polymorphism, however, I think I will be changing that to use the Stream class, which is the base class of both HardwareSerial and USBSerial, but not SoftwareSerial - something that needs addressing.

And I'm not sure what you mean about stopping using it as a PORT? My guess is that whatever you were interfacing to pins 0 and 1 was affecting the serial while other pins that were interfacing to it were active.

For high speed reading/writing of 8 bit values you should use pins 26 to 33, which map to port E pins 0 to 7 in order. Then you can read the whole byte with

byte val = PORTE;

or

int val = PORTE &amp; 0xFF;

as long as the pins are set into input mode.

I used that port as the main IO port for my 256KB RAM expansion experiment


guymc

Fri, 13 Sep 2013 18:02:24 +0000

  1. Is there a software serial implementation for chipKIT?

Software serial is a built-in library, and is working fine for me. I use it to drive a 4 digit display from SparkFun at 9600 baud. It worked perfectly on the first try, as I recall. I can post some sample code later tonite, if you need it.

Cheers


unexpectedly

Fri, 13 Sep 2013 18:39:47 +0000

Up until now I hadn't bothered with OOP for a menu. Things are changing though as I learn more about polymorphism in C++ (up to now I'd only really used it in Java). These PIC32 chips, you see, have multiple hardware serial ports. So just use those pins and reference Serial1 instead of Serial. You could pass the serial device to the class in the same way I do the DSPI object in ST7735, so you can select which port to use. You can look at ICSC for an example of how I do it with Serial.

I'll give a go with hardware serial on Serial-not-1. I'm using an Arduino proto shield on the chipkit, so the 2nd row of pins inboard are linked... oh wait, I can cut the traces! OK I'll look at it all over again. :D

And I'm not sure what you mean about stopping using it as a PORT? My guess is that whatever you were interfacing to pins 0 and 1 was affecting the serial while other pins that were interfacing to it were active. For high speed reading/writing of 8 bit values you should use pins 26 to 33, which map to port E pins 0 to 7 in order.

Exactly the same, but that project is all AVR, where "PORTD" is D0-D7. I believe the mode wasn't entirely responsible for the problem; couple the mode and also what the IC was doing to lines D0 and D1.

Yes, I agree about setting up a port for 8-bit transfers. :)

Software serial is a built-in library, and is working fine for me. I use it to drive a 4 digit display from SparkFun at 9600 baud. It worked perfectly on the first try, as I recall. I can post some sample code later tonite, if you need it. Cheers

That would be great, thanks! Maybe also start a thread in Libraries titled "Simple SoftwareSerial usage example" ?? I did google a bit and the big problem us ardweeny guys have is there aren't (m)any examples for Google to find on how to do simple things.

Thanks! Chris


majenko

Fri, 13 Sep 2013 18:45:42 +0000

Which protoshield are you using?

Serial numbering is a little strange.

The main serial, whatever that may be, is "Serial" - be that hardware serial on pins 0/1, or USB serial through CDC.

If you have CDC, then pins 0/1 serial is known as Serial0

The second serial port is Serial1, and the other serials (on the bigger boards) are Serial2 up to (depending on board) Serial5.


unexpectedly

Fri, 13 Sep 2013 19:00:52 +0000

What's CDC?

This protoshield. I love it for the I2C corner, where I put on a low profile right angle header and also added pull-up resistors. Plus, this project has connectors on all 4 sides, so I need all the usable pins I can grab around the perimeter. This one and the Adafruit one are best for that. If you want an Adafruit one, let me know, I'll post you a couple. I accidentally bought some forgetting that I already had a couple. Did it twice.

I'll de-solder my printer pins and then likely solder them to 0-1 just because I really can't be bothered to use serial monitor. It is very anti-menu/TFT!! I've got my menuing set up so I can test the stepper motor and get back to trying to complete this project...

The bit about Serial, Serial0, or Serial1? I was already assuming similarity to how DSPI0, et al, works. I just hope Serial works better for me than DSPI did at first. ;) Thanks for your code! I'll look that up, do some soldering, and get to experimenting. :D


majenko

Fri, 13 Sep 2013 19:12:48 +0000

What's CDC? This protoshield. I love it for the I2C corner, where I put on a low profile right angle header and also added pull-up resistors. Plus, this project has connectors on all 4 sides, so I need all the usable pins I can grab around the perimeter. This one and the Adafruit one are best for that. If you want an Adafruit one, let me know, I'll post you a couple. I accidentally bought some forgetting that I already had a couple. Did it twice.

Nah, it's ok thanks - I make my own.

I'll de-solder my printer pins and then likely solder them to 0-1 just because I really can't be bothered to use serial monitor. It is very anti-menu/TFT!! I've got my menuing set up so I can test the stepper motor and get back to trying to complete this project...

I'd be nervous about putting a printer on pins 0/1, as it might print your HEX file out as you upload it ;)

The bit about Serial, Serial0, or Serial1? I was already assuming similarity to how DSPI0, et al, works. I just hope Serial works better for me than DSPI did at first. ;) Thanks for your code! I'll look that up, do some soldering, and get to experimenting. :D

Serial is far simpler that DSPI, since it is based on the original Arduino serial code.


unexpectedly

Fri, 13 Sep 2013 19:40:11 +0000

(regarding proto shields) I make my own.

NICE - That's a great layout!

I'd be nervous about putting a printer on pins 0/1, as it might print your HEX file out as you upload it ;)

:shock: thanks for saving me that experience... :?

:D Chris


unexpectedly

Sat, 14 Sep 2013 00:37:03 +0000

Awesomesause, I actually made the printer work on the 1st try. I do believe that's a second for me! Pulled off the start of my Thermal printer class for chipKIT with minimal code!

I took apart the stack and just shoved wires into pins 39 and 40, then put the stack of shields back together. The wires pushed in those pins don't even touch the proto shield.

//  Thermal.h
	#include &lt;WProgram.h&gt;
	#include &lt;HardwareSerial.h&gt;
	class Thermal {
		public:
		Thermal(HardwareSerial *sdev, uint32_t baud );
		void begin( void );
		void test();
		protected:
	    HardwareSerial *_hserial;
	    uint32_t 	_baud;
	};

The one thing I kinda wish I could do was:

class Thermal : public HardwareSerial

which would let me call println() from anywhere and not have to _hserial->println(). Trying that class declaration brings up a nasty compiler error about no matching prototype. Hardware serial has a huge constructor and all of this is complicated by how Serial1 is automagically constructed already. There needs to be another HardwareSerial::HardwareSerial() with empty constructor in the Library so I could do what I want. :D

Moar code:

//  Thermal.cpp
	#include &lt;Thermal.h&gt;
	Thermal::Thermal(HardwareSerial *sdev, uint32_t baud ) {
		_hserial = sdev;
		_baud = baud;
	}
	void Thermal::begin( void ){
		_hserial-&gt;begin(_baud);
	}
	void Thermal::test() {
		_hserial-&gt;println("Hello World!");
	}

And finally the sketch:

//  in the sketch:
	#include &lt;HardwareSerial.h&gt;
	#include &lt;Thermal.h&gt;
	Thermal printer(&amp;Serial1, 19200);

	void setup(){
		printer.begin();
		printer.test();
	}

And it printed!! :D The printer is still "set up" from when it was working in my Arduino land, so hard to say if it would "just work" for the visiting Googler who just got their printer. ;)

Next steps:

  • finish out an implementation of Thermal library
  • tweak the lame defaults, or come up with a set of defaults that work better on my 9V supply. Everyone who built these libs found they needed to really slow things down for the printer to work. When feeding it 9V, it is much happier, so I'm going to start pulling out all the delays I can.
  • Decide if my OCD means I need to make the wiring to pins 39 and 40 permanent.

Making pins 39 and 40 permanent means I can't use the NKC shield, as its pins inside of D8:15 are offset and do not line up with the chipKIT. Although I could just drill them out. Or I can take the Adafruit proto shield still populated from my Adruino configuration, cut the traces to GND for 39 and AREF on 40 and put pins there. At least it is physically compatible.

I've got a NKC chipKIT proto shield:

  • pins 39 & 40 will work without issue
  • lots of rows tied together, so it'll be easy enough to solder some things
  • None of the shields pins are exposed, so any pin I tap into which gets a stacking header needs to have a wire soldered to the pin that goes into the uC32 (my OCD doesn't like this)
  • They route +5V everywhere with no consideration for 3.3, so I'll have to cut the 5V trace and jump the 3.3 for sensors there.
  • Doesn't have the I2C that NKC did for Arduino

Freetronics and MAKE proto shields:

  • Are "proper" and simply integrate pin 39 into the ground plane. I'm not going to bother.

Arduino proto shield:

  • GND for their entire shield comes from pin above D13 with a huge trace across pin 39 that then feeds the rest of the shield.

Adafruit proto shield:

  • Nice thin traces from GND across our pin 39

Oh, right, NONE of the Arduino proto shield's inner rows of pins are spaced properly. Oops. That changes everything. A "permanent" solution therefore will somehow involve the NKC proto shield. It is the easiest to route the 3.3 and 5V the way I want and also breaks out the I2C in that corner by A4/A5, which really makes me happy.

I've got a spare NKC proto shield in case I screw this one up hacking it. So maybe 39 and 40 will just remain the solid wires shoved into the uC32's header!


unexpectedly

Sat, 14 Sep 2013 05:45:27 +0000

Grrrr... everything was going splendidly. Then I added a "\n" and it pretty much ruined the printer settings. wth. It prints but has lost the ability to make some things happen.

There's an unexplained correlation between mode settings that's not yet explained...


majenko

Sat, 14 Sep 2013 08:17:42 +0000

PM me your address, I'll send you a complementary proto shield. I designed mine so it would work with the ChipKit by cutting traces.

When you inherit Print it is required that you implement the write function

void MyClass::write(unsigned char c) {
...
}

This function is called on a per-character basis by the print and println functions and is used to actually output the character to your intended device. You would use this as a simple wrapper to the write() function in the HardwareSerial device.


unexpectedly

Sat, 14 Sep 2013 10:11:20 +0000

It's not write, it's the constructor to HardwareSerial, they only have two prototypes and they've got about 25 arguments each. :P

BTW, attached is a VERY working Thermal lib. No bitmap support yet... I'll mess with that tomorrow. :D


majenko

Sat, 14 Sep 2013 11:07:29 +0000

Inherit print, and remove your print and println functions, then you can use all the standard print and println overloaded functions for string, char, int, float, etc.


majenko

Sat, 14 Sep 2013 11:25:19 +0000

You could always integrate it with the TFT experimental system - make it a display device (inherit TFT) and have the update() function take a framebuffer which then prints the whole framebuffer as a graphic ;)


majenko

Sat, 14 Sep 2013 13:15:09 +0000

I am pondering the concept of turning this TFT thing into a completely self contained new programming environment for the chipKIT. A complete collection of libraries and drivers all in one big library, where everything plugs together. Devices for different chips, and drivers to communicate with them. One big powerful OOP monster.

I don't know if you've ever come across Cosa, but it could be a bit like that...

Could be nice...


guymc

Sat, 14 Sep 2013 21:03:10 +0000

Here's that Software Serial example:

#include &lt;SoftwareSerial.h&gt;

// assign pins for RX, TX
#define LED1 14
#define SERIAL_PIN 0

// define a soft serial port (RX, TX)
SoftwareSerial mySerial =  SoftwareSerial(LED1, SERIAL_PIN);

// ...and so on

// Put this statement in setup()
  mySerial.begin(9600);  // set the data rate

// Print a 4 digit number
  char tempString[10];
  unsigned int frequency;
 
  sprintf(tempString, "%4d", frequency); 
  mySerial.print('v');  // clear the display
  mySerial.print(tempString);

unexpectedly

Mon, 16 Sep 2013 16:41:27 +0000

I have something of a thermal lib working :) [attachment=0]thermal.jpg[/attachment]

As normal, the code out in the wild for Arduino is quite varied. I wish I had done more to study Adafruit's code initially. But as I google'd and found a proper reference, I'm hoping some tweaks to the code I've got will make it ready for me to share. :)

Right now, I kill the buffer to the printer if the image is too big, so I'm going to try and use the printer's built in "transceive buffer full" communication to pause printing. Not sure. Adafruit has a per-byte delay based on the time it takes to communicate at 19200 baud (which also assumes 11 bits sent per byte).

Add to that the printer has some kind of "heat delay" and another "print delay". Not sure how they all tie in, but the Ada guys put some effort into tweaking their delays.


unexpectedly

Tue, 17 Sep 2013 06:07:53 +0000

Ummm... :? are there any clear-cut (and simple / dumb) examples of attaching a function to timed interrupts?

Actually what I'm after is attaching an interrupt to the RX pin on UART2. I'd like to monitor if the printer tells me it is going to overflow. If it does, then I can stop the too-large image transfer until it's ok to keep going.

But I don't mind using a too-fast timer interrupt for this test scenario. I just want to see if it's possible to test for "receive buffer full" before I overflow it and kill the whole thing.

The alternative is to implement a delay on my write() wrapper... :P It just feels like the right way would be to catch the printer telling us BUSY (if that's possible). This is in the ESC/POS literature ... and may or may not be implemented on this cheesey thermal printer. Tho, I have a feeling it is, as the datasheet with it mentions full RS232 is available, they just populate RX/TX to save the buyer $.

:) Chris


majenko

Tue, 17 Sep 2013 08:41:06 +0000

Yes, there are ways of doing it. The problem is that you have multiple layers of buffering that get in the way. Mainly the hardware transmit FIFO, which can be 4 or 8 characters deep depending on the chip on your board.

What I would do is wrap the serial writing in a function, and make heavy use of the flush() function. That ensures that all data has been transmitted out of the hardware before continuing. (Note: on earlier versions of Arduino [<1.0.0] and MPIDE [quite recent] the flush function purges the receive buffer). I would also include in that function probing to see if the printer is busy or not through whatever means are provided by the printer (XON/XOFF, hardware signalling, etc).

The typical sequence is:

// Wait for it to not be busy
while(printerIsBusy()) {
  continue;
}
Serial.write(byte); // Send the next byte
Serial.flush(); // Wait for that byte to have been sent

The printerIsBusy() function could be a probe of a GPIO line connected to CTS, or DTR, or whatever, or it could be reading the serial input to see if a "busy" or "clear" character has been sent, or whatever method the printer requires.


unexpectedly

Tue, 17 Sep 2013 19:14:10 +0000

Right now, I only have RX/TX and they have some kind of reply capability if I actually read() it. Maybe part of write() will be to first read()?


majenko

Tue, 17 Sep 2013 19:29:45 +0000

printerIsBusy() will involve reading, yes.


majenko

Tue, 17 Sep 2013 20:10:41 +0000

Oh, and in answer to one of your earlier posts...

Yes, I can use the SD card slot on my TFT screen. Provided:

  1. I use my heavily modified SD library that actually uses SPI, and
  2. I don't use the TFT.

As soon as you start outputting data to the TFT it kills the SD card communication.

If you do the following sequence:

  1. Initialize TFT
  2. Initialize SD card
  3. Do SD card operations
  4. Output something to TFT

it all works. However, if you do:

  1. Initialize TFT
  2. Initialize SD card
  3. Output something to TFT
  4. Do SD card operations

then step 4 fails miserably.

The SD library is shockingly bad. It's basically a direct port of the Arduino one with a half-arsed conversion of the SPI code to work on the PIC32. I say half-arsed, because although it has bits around the place for hardware SPI, none of it is actually used. It's all software driven, and badly done at that.

One of my desires (if you can call it a desire) is to re-do all the SD card code. I'd like to re-write all of the SPI code as well, and make it all work properly. Maybe I'll start off by writing a new SPI library that is much more OOP than the existing stuff. Something like:

// Create a new SPI device on SPI channel 0, with CS pin 27, running in mode 0 at 1MHz
myDevice = SPIDevice(SPI0, 27, MODE0, 1000000UL);

and then you just

myDevice.transfer(0x69);

and

uint32_t myData[1024] = {... random data here ...};
myDevice.bulkWrite(myData, 1024);
myDevice.bulkRead(myData, 1024);

etc.

The device could use DMA to handle the actual bulk transfers. Maybe have it so you can kick off a transfer in the background, too.


unexpectedly

Tue, 17 Sep 2013 22:56:25 +0000

OMG, majenko that's "aggro" !! You're like the Chuck Norris of chipKIT!

Sooooo... I added a delay to work on my bitmap printing problem. Once my delay got down around 500 usec, the 384x384 box with 2bit border always takes 9.6 seconds to complete. With the delay at baud/33 = 581, the box takes 10.7 seconds.

Part of the error of the delay is that printing a dot takes more time to print than not printing a dot. So while my exact case of a mostly empty 384 bitmap can get away with delays under 500 usec, it could be that adding more bits would cause an overflow (and thus I should be trying to check if the printer is talking back). But... I haven't arsed to check it and probably wont either.

Now, I want to sweep my TPS sensor and plot its data in the box to make a graph!! [attachment=0]ptr_bitmap_delay.jpg[/attachment]


majenko

Tue, 17 Sep 2013 23:31:41 +0000

Looking good. You really should probe for the busy state, you know...

I have made a start on a replacement for DSPI.h - SPIDevice.h. It's device-centric, not bus centric, and it has methods for bulk transfers.

No DMA yet. I just noticed that some of the PIC32s don't have any DMA, like the one that's on the UNO32. So I need some way of working out whether or not to include the DMA code, and which channels are available.


unexpectedly

Wed, 18 Sep 2013 00:36:15 +0000

Whoops about the Uno32. :P In the true Murican way, I just buy uC32 by default from now on. :roll: :lol:

Yeah, so the concept of Online / Offline is getting me to start trying to receive from the printer its status. Nevermind that the documentation has no mention of offline or online. Rather the wake() and sleep() methods in thermal use the ESC/POS "ESC = n" command called "Select peripheral device" which when is set to 0, the printer ignores everything on the serial line until a ESC = 1 command comes then it doesn't.

There are apparently 4 ways to get a status. I started with "GS r". _status is an int member of the class.

int Thermal::status( void ) {
	//  GS r 1
    writeBytes(29, 114, 1);
    _status = 0;
    int tmp = 0;
    while( _hserial-&gt;available() ) {
	    tmp = _hserial-&gt;read();
	    if( tmp != 0 )
	        _status = tmp;
	}
	return _status;
}

So in my code I have a local int that I assign the return from printer.status() to. Then I sprintf the result in to a string "Status: %d" and print it. The uC32 locks up after printing "Sta". I tried not using the returned value at all. Same result. Comment out the call to printer.status() and all acts normal.

So something is losing its mind there ... is it possible program control never returns from the call and is stuck in the while? (I normally would dismiss this idea since we actually tft.print() something)

Is the above way the correct way to read()? How do I simply attach the RX pin to an interrupt which would then handle the read()?

Hmph. The source of this issue is that I want to turn off the printer while screwing around with other things so it doesn't print out the header every time I restart. :) Though I could just always wake() and then sleep() or not in setup. :P


majenko

Wed, 18 Sep 2013 07:13:10 +0000

I don't see why that should cause a lock-up. There's only one thing wrong with your methodology, and that is that you're not waiting for the response to arrive.

The delay between you sending the GS r 1 command and its reply coming back will most probably be greater than the time between you sending the command and expecting the result to be there.

You should really:

  1. Send the command
  2. Wait for the response to arrive ( while (_hserial->available() < 1); )
  3. Read in the contents of the serial buffer.

If you're expecting more than one character to be sent back then you should wait for all those characters to be in the serial buffer together, rather than just the first one.

Your current while loop will only run if the response arrives within a couple of nanoseconds of the command being sent, and that won't happen with serial communication. It will also only remember the last character it received.


unexpectedly

Fri, 20 Sep 2013 09:56:34 +0000

Hmmm, good food for thought, thanks for that.

I've got it sweeping the throttle position sensor, recording the data, printing on the TFT (all of which is copied directly from my working Arduino code). And now, it is setting the bits in the box384 array and those bits are (barely) printing. Time to now implement the same line() function that the tft uses for my uint8_t *bitmap in memory. Oddly, box384data[offset] behaves differently than making a uint8_t *bitmap=box384data and then addressing it as *(bitmap+offset). The offset values and bits I'm setting all make sense, too. Kinda weird.

Also, a dumb newb question: is there a way I can set the entire 19k box384data[] array to all zeroes? It's easier to build a function to write in the 0xFFs, 0xC0s, and 0x03s for the border than to iterate through the whole dang thing. Of course, the PIC32 is so fast, one probably wouldn't notice the difference. :P


majenko

Fri, 20 Sep 2013 10:09:20 +0000

To answer your second question first: memset().

memset(box384data, 0, 19000);

Replace 19000 with the actual size of the array, and the 0 is the byte to set everything to.

Internally that just does a for() loop setting each byte to the specified value.

And now to work backwards:

You could use the experimental TFT system for your printer. Create a Framebuffer object pointing to your image buffer, and then use that to draw and print. You can then get at the data inside the Framebuffer by calling the .colorAt(x, y) function. Of course, that would then be using 8 bits per pixel, whereas you only really need 1 bit per pixel, so maybe it's overkill.

I have been thinking that we should have a number of different framebuffer depths available, so a 1-bit framebuffer which packs the data into individual bits would be absolutely ideal for this.

And working with array offsets, and pointer offsets should yield the same results. It's something I do regularly. The only caveat is that it can mess the pointer values up depending on the size of the target variable (8, 16 or 32 bits), so for a uint8_t, if P == 0x00, P+1 == 0x01, and for 32-bit, P+1 == 0x04. But you're working with uint8_t, so that shouldn't be an issue at all.


majenko

Fri, 20 Sep 2013 10:39:06 +0000

And speaking of 1-bit framebuffers - I have (I think) just created the Framebuffer1 virtual device in the experimental system. A 1-bit framebuffer virtual device you can use with TFT devices using their builtin .update(fb) function, or manually using the .colorAt(x, y) function of the framebuffer.

By the way, the .colorAt(x, y) function returns the resultant colour translated from the palette (which has 2 entries), and defaults to black (0x0000) for bit off, and white (0xFFFF) for bit on. You can change those mappings with .setColor(0/1, 0x0000 - 0xFFFF), or use any of the 237 colour mappings in the Color::<name> library (see Color.h for the full list - it's ripped from X11R6's rgb.txt).


unexpectedly

Fri, 20 Sep 2013 19:41:09 +0000

What I've got right now is an array of ADC ints with about 116 members. I first send (*test, idxmax) to the tft graph function which maps the array from idx,ADC to an x,y between 1,1 and 160,220. Then I send (*test, idxmax) to the thermal graph func which does this: [attachment=0]friday.png[/attachment] A few problems with just dumping the framebuffer:

  1. need to scale to different resolution for printer
  2. the dots themselves aren't cutting it; going to do something for line()
  3. I'm still afraid of all the classes. :roll:

The dots can be seen if you look closely enough, so working on that all now. This would be another great example for a class. :roll: Maybe I'll give it another go. This might be simple enough I can handle it on my own. Then I can make a bunch of little helper functions and not keep passing around the image size, just have members for that.

updated algorithm: the xByte was wrong, needs to shift from left.


majenko

Fri, 20 Sep 2013 20:34:25 +0000

(btw, image whipped up quickly in inkscape, <3 that program!)

As it happens I have it open and am working on some graphics in it right now :P

A few problems with just dumping the framebuffer:

  1. need to scale to different resolution for printer

Create a different size frame buffer?

  1. the dots themselves aren't cutting it; going to do something for line()

Line() just creates dots at the end of the day. If you don't join the dots up though then you'll get dashes.

  1. I'm still afraid of all the classes. :roll:

I used to be too. Now I can't get enough of them ;)

The dots can be seen if you look closely enough, so working on that all now. This would be another great example for a class. :roll: Maybe I'll give it another go. This might be simple enough I can handle it on my own. Then I can make a bunch of little helper functions and not keep passing around the image size, just have members for that.

If you had it all in a class then the functions would all know the size already...


unexpectedly

Fri, 20 Sep 2013 20:57:37 +0000

I noticed nusanced behavioUr of line functions among graphics programs and some err on side of single pixel, some double. I think I see how I can implement a double row. Single dots on printer don't have enough time to show, but start laying them down and that's when things show up.


unexpectedly

Fri, 20 Sep 2013 21:00:13 +0000

Crap already running into problem of how do I get globals into my class. :( So annoying; no wonder grumpy C embedded guys are so grumpy.


majenko

Fri, 20 Sep 2013 22:09:11 +0000

LOL

You don't use globals in classes. You use class member variables, and instantiate them in the constructor.


unexpectedly

Fri, 20 Sep 2013 22:53:47 +0000

I mean globals from the program itself. Yeah, made members in the class and used the constructor to initialize. I got line working, now to make it thicker. :P