Digole UART/I2C/SPI Display Library

@RWB, looks fantastic! Glad you are having fun.

I use Notepad++ and it lets me select columns by pressing the ‘Alt’ key while selecting with my mouse. I love that editor, especially the “reindent C++ code” for cleaning things up. :smile:

rickpbush, did you figure it out?

1 Like

Hi, yes, I felt like an idiot in the presence of masters so I deleted my post :stuck_out_tongue:

Mosi is data, the screen is write to only and is a slave so it must be master out slave in, now I’m sitting here trying to figure out my ss lines, one for the screen, one for the sd right? but then I’m looking at the data sheet for the spark thinking why is ss labelled on the spark also, is it so the spark can be a slave, can I just connect ss on the screen to say d0 and ss on the card reader to say d1, then set d0/d1 high/low depending on which device I want to use at the time?

Ok, I got this code

`void setup() {

pinMode(digoleSS, OUTPUT);
pinMode(SDCardSS, OUTPUT);
digitalWrite(SDCardSS,HIGH);
digitalWrite(digoleSS,LOW);

digole.begin();
digole.disableCursor();
delay(500);
digole.clearScreen();
delay(50);
digole.print("Signal : ");
//digole.print(Network.RSSI());

}

void loop() {

delay(500);
digole.setPrintPos(9, 0, _TEXT_);
digole.print("    ");
digole.setPrintPos(9, 0, _TEXT_);

digole.setTrueColor(255,0,0);
digole.print(Network.RSSI());

}`

its a bit ‘flashy’ where I redraw the signal strength, am I clearing the area correctly using spaces?

1 Like

rickpbush,

The Spark SS pin is set to A2 by default but the SPI code does not control that pin. That is done by the libraries that control each SPI device. When you call the Digole constructor, you specify the SS pin so you can specify what you want. Depending on the SD library you use, you specify the chipselect pin as well. The pinMode is taken care or by each library so you don’t need this:

pinMode(digoleSS, OUTPUT);
pinMode(SDCardSS, OUTPUT);
digitalWrite(SDCardSS,HIGH);
digitalWrite(digoleSS,LOW);

The setup() code also needs to be rearranged. The digole.clearScreen() needs to be followed by a command to work and already does a disableCursor(). The is no need for delays since the SPI commands are buffered on the Digole. So the code should look like this:

digole.begin();
digole.clearScreen();
digole.print("Signal : ");

As far as using spaces to clear the text area, that is the right idea but spaces take less space than characters so you may need more of them. I sometimes draw an empty rectangle to blank out text but in your case, spaces are fine. You call digole.setTrueColor(255,0,0); in loop and that only needs to be done once so it should be in setup(). :smile:

Hi Peekay, thanks for the explaination, so I just tell the SPI device (in the case of the digole via its constructor) which pin its ss is connected and then forget about it, that’s great.

So if I have an SD and digole attatched, when I read or write to the card the SD library will set its ss low, and because I’m not interacting with the digole, presumably the digole library will have set its ss pin to high.

I did think about drawing a rectangle to clear areas of the screen and when I start creating more elaborate stuff on the screen I will have to.

I called setTrueColor in the loop because this is a bit of a contrived scenario, I will have much more going on in the loop after this, so might print green text, then yellow etc.

I found this SD library which i want to use SD Library but there are so many files it’s getting cumbersome if impossible to use the web IDE so I’m off to see if I can find a decent tutorial on how to set up a more capable local enviroment, I use Textpad for web dev which can link to compilers etc but I’d like to get into source insight which my brother suggested for c++, it looks like a decent IDE.

rickpbush, most if not all SPI device libraries will allow to specify their chipselect line. SPI is transactional so the libraries will lower and raise the CS lines on each transaction, leaving the line high as required by the SPI protocol. This allows many SPI devices to co-exist.

THe SD library you found is one BDub and I worked on together and it works well. Eventually, there will be a Core firmware library that can handle SD and flash for create files.

As for the IDE, the guide for creating a local toolchain is here. If you search on the forum you will find instructions on installing Eclipse and Netbeans as IDEs on Windows but I have not seen Source Insight (most likely since it costs money). Personally, I use Notepad++ to edit and run make manually.

One tool I use a lot is Spark CLI, which allows me to compile using the cloud and also remotely flash my cores. This tool does a lot and has come a long way and is improving rapidly. :smile:

peekay, I didn’t want to pollute this thread with talk of IDEs etc so I’ve sort of continued it here

Hi, me again :stuck_out_tongue: I have fianlly got Netbeans up and running, included the SD library and reorganized digoleSerial into a file structure with a make file so it works in the IDE. I have the following code but it only gets as far as displaying Initializing SD Card, then nothing?

#include “SdInfo.h”
#include “Sd2Card.h”
#include “SD.h”

#define Digole_Serial_SPI
#include “DigoleSerialDisp.h”

#define digoleSS  D0
#define SDCardSS D1

File myFile;

int lineNo = 1;

DigoleSerialDisp digole(digoleSS); //SPI

void newLine();

void setup()
{
    digole.begin();
    digole.clearScreen();
    
    digole.print(“Initializing SD card”);

if (!SD.begin(SDCardSS))
    {
        newLine();
        digole.print(“SD init Failed!”);
        delay(2000);
        return;
    }
    
    myFile = SD.open(“test.txt”, FILE_WRITE);
    if (myFile)
    {
        newLine();
        digole.print(“Write to test.txt”);
        myFile.println(“testing 1, 2, 3.”);
        myFile.close();
        newLine();
        digole.print(“done.”);
    }
    else
    {
        newLine();
        digitalWrite(SDCardSS,HIGH);
        digitalWrite(digoleSS,LOW);
        digole.print(“error opening test.txt”);
    }
}

void newLine()
{
    digole.setPrintPos(0, lineNo, TEXT);
    lineNo++;
}

void loop() {
   
}

rickpbush, check your wiring. You may also want to disconnect the Digole and use the serial port for debugging just to be sure.

Ok, I’m on it :smile:

Well, all is well wiring wise, got expected serial output, the card has also been written to so it’s just the digole isn’t updating past the first write?

I have replaced the contents of setup with
    digole.begin();
    digole.disableCursor();
    digole.clearScreen();

digole.println(“Initializing SD card”);
    digole.println(“wallaby”);
    digole.println(“badger”);
    digole.println(“house brick”);

and put a digole.println("-"), delay(1000) in the loop.

Now that the sd card code is gone, the digole behaves as expected and I get four lines of text and some - on screen. I suspect the problem is a bug in the sd library as after calling SD.begin the digole refuses to do anything.

peekay, thanks for your time so far, I have narrowed the problem I’m having down to this,

Any commands issued to the digole after calling SD.begin will not show on the screen.

I have looked into SD.begin which uses sd2Card.init which in turn calls

SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV4);

the digole uses

SPI.setClockDivider(SPI_CLOCK_DIV32);
SPI.setDataMode(1);

could this be why it’s going wrong. I’m afraid I feel a bit lost meddling in the digole and SD library sources :frowning:

rickpbush, I had a hunch it might be the SPI setup. You’ll notice each library sets up a different SPI mode and speed. The speed is easy to get around but not so with the SPI mode. Neither library maintains the SPI configuration “context” as they are called so the SPI is set based on the order of your setups! My question to you then is, are you is able to use Serial1 to communicate to the Digole instead of SPI? If you are displaying primarily text, serial at 115Kbaud is more than fine (that’s how I use the Digole).

I had not used the digole/SD combo in SPI which explains why I did not find this problem. :open_mouth:

Hi peekay, I’m so glad I wasn’t just being a plonker. I did concider using another way to comunucate with either device, I want maximum speed comunicating with the screen so I’d like to use SPI for that, I may look into using UART or I2C for the sd card as that doesn’t need to be fast.

It does however raise a bit of a problem though, I assumed the point of SPI was that you could have multiple slave devices using the same bus but if each device requires the bus to be setup in a different way doesn’t that kinda negate the usefulness?

I’m wondering if there is a way, similar to the SS situation, whereby each library could relinquish control of the bus settings when it’s not using it so that when other slave devices use it they can set it as they need to. Anyway, way out of my league so I’ll look at using different buses for the two devices, this does mean I’m going to run out of pins for my project though, o well, sez la vie.

rickpbush, it is possible to modify the SPI code in each library so that each time you write to an SPI device it resets the SPI settings for that device. This will slow the transfer times considerably I suspect. There may be a way to do it faster but I need to take it up with the Spark Team. The ideal is an SPI bus “broker” that handles all transactions between the Core and the devices.

Ok, thanks peekay, it looks like it may be possible to use software spi for the sd and hardware spi for the digole if I can find enough free pins, else i2c for the digole and spi for the card

rickpbush, if I have time before the Maker Faire I will experiment with the Digole/SD SPI combo to see if I can get them to play together.

A few years back I ported then Adafruit TFT 1.8 display and SD to the Maple and ran into the same issues. The hardware mode and clock speed settings are just a few bits in the SPI registers so there is minimal overhead in setting them for each SPI operation. So rather than setting the params in the constructor, or open/begin functions, save the params there and set them on api read and write.

I believe I had to run a slower clock speed on the SD than on the display, and the mode settings were the same (for the 1.8 TFT)

pra, that’s excactly what I was thinking. The SPI registers are shared with the I2C and it’s just a matter of figuring out how to do it without affecting other parts. There is an SPI register data structure that gets setup and I believe I may be able to use.