LiquidCrystal & Shift Register

@korneel Let me try to create a fix based on some things I’ve learned over the last couple days.

EDIT: @korneel @Soulhuntre @Dave give this a try! I don’t have it hooked to an LCD, but the code is running, and SPI CLK is banging out the A3 pin, data on the A5 pin. A2 is latching like a good latch should.

FYI: This is a new GIST since the old one was a Secret gist by mistake. I’ll put a link in the old one to the new one! :smile:

Technically this should be level shifted for a 74HC595, but I have been running 595’s at 3.3V on the core and they do seem to work, just try it first!

Basically in the code I moved all of the initialization of pins and stuff to the user setup() routine… so you have to call lcd.initSPI(); now from code just once. You also must call lcd.begin(16,2); with the right configuration. I also added a blinking D7 led so we can tell if it locks up or not. Delete that if you want. Also slowed down the SPI to 4.5MHz, instead of 9MHz just so we can give it a chance to work… if it works, crank up the speed and see how fast she’ll go. I’m thinking the faster you go, the more you are going to want to level shift it to 5V.

Awesome! I’ll try to get somebody here to dig out one of these screens and run it :smile: Thanks @BDub!

1 Like

just let me know if i can do anything… i might not know everything about coding, but at least i can solder… :smile:
i have almost every component you can think of lying around…

1 Like

@korneel yeah just try the latest code I posted above if you have a LCD with 74HC595 setup already. Thanks!

so there is good news and bad news.
good news : core does not crash anymore!
i can see the D7 LED flashing rather quickly, so that seems fine. also the core remains responsive.
bad news, doesn’t display anything on the screen.

i can post my pinout?

Make sure your RW pin of the LCD is connected to GND !

Good point @mohit the original hookup drawing that is supposedly known working doesn’t have that connected!

It is in a comment under the picture though! Doah.
Note:I had to connect pin 5 on the LCD to gnd (not on diagram) to make it work.

Need to make a Spark Core Fritzing diagram for this now :slight_smile:

2 Likes

will check tomorrow. i do have to say that i did use the same wiring with a “standard” arduino and that worked…

so i’ll check and report back.
also, wouldn’t it be great if such a fritzing diagram builder could be integrated into the spark cloud? that would work so well with the online sketch building!

Fritzing makes me wanna punch babies when I use it as a stand alone program… I can’t imagine how it would be as a memory hungry browser application!!! However http://123d.circuits.io has managed to figure out how to do it, AND simulate an Arduino at the same time… so, apparently it’s possible for Fritzing to play nicer.

Just made this, let me know if you see any errors :smile:

2 Likes

so this is indeed what i’ve build… although i did switched A02 and A03 initially. i’ve just changed this, and still no go :confused:

I haven’t had a chance to test it since I don’t have the shift register here. Did playing with the contrast pot help? LCD might appear blank if the contrast isn’t set right.

I’m currently testing this with the SPI mode of the Adafruit SPI/I2C LCD backpack… it basically makes the wiring easy. However you have to flip rewire the code for EN, D4-D7, as those are wired differently than the Fritzing diagram I made above.

That said, it wasn’t working at all. SPI looks like total crap on my scope, so at first I swiched to using shiftOut() which was much cleaner… but slow. Then I decided to roll my own shiftOut() using direct gpio manipulation, but the delays are questionable so I switched back to shiftOut()… even though it’s slow it should initially work.

And after a few more tweaks, got it working!

Then I turned to getting my faster version of shiftOut() working. Got it! About 3x faster. Just about as fast as the hardware SPI set to 4.5MHz :smile:

Imgur

Added on/off backlight control, and I need to clean up the library now. It’s SoftSPI so you can define any 3 digital pins to use instead of having to use the hardware SPI pins which are on the analog side of the :spark: Core. I’m going to redo the Fritzing diagram to use the same wiring that’s on Adafruit’s Backpack… so we don’t have to define multiple build types in the library.

FYI, you do have to adjust the contrast pot on the Adafruit I2C/SPI LCD Backpack (mostly clockwise) or you won’t see anything. I would have thought they’d at least jam this fully clockwise, but they expect you to probably read their tutorial. RTFM? Hell no!

Now to see what’s up with SPI… because I would like this to be even faster! (9MHz)

FYI: This is what I’m seeing on SPI… probably what’s making it fail on something like this 74HC595 where the SS pin controls the OUTPUT LATCH and does not gate the part like a normal chip select would. Otherwise it would ignore this garbage. @timb do you see this as well?

BTW this looks much faster than my SoftSPI, but there is a lot more delay between bytes transferred with the hardware SPI for some reason…

For comparison, here’s the SoftSPI I implemented.

2 Likes

I wonder if this has something to do with the SPI data output MOSI being defined as AF_OUTPUT_PUSHPULL instead of the more normal OUTPUT:

https://github.com/spark/core-firmware/blob/master/src/spark_wiring_spi.cpp

That funny intermediate voltage and those spikes make me think that the pin is not being setup correctly here.

I like your SoftSPI @BDub!

Thanks @bko! In the interest of “just trying it” I changed the SCK and MOSI pins to OUTPUT’s and SPI doesn’t even work anymore … it’s also locking up and not running the user code. Probably failing in the SPI init stages.

I’ll keep looking! Probably would make sense to trim this down to JUST sending SPI data and nothing else for the time being.

EDIT: Ok this code produces clean SPI clk/data, now to figure out why my other stuff is lookin’ funky.

#include "application.h"

bool s = false;

void setup() {
  SPI.setClockDivider(SPI_CLOCK_DIV16); 
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.begin();
  pinMode(D7,OUTPUT);
}

void loop() {
  digitalWrite(A2, LOW);
  SPI.transfer(0x55);
  digitalWrite(A2, HIGH);

  s = !s;
  digitalWrite(D7,s);
  delay(100);
}

I just found the problem and fixed it!

Arduino library was constantly re-configuring up the SPI which was glitching the bus:

void LiquidCrystal::spiSendOut() //SPI #############################
{
  //just in case you are using SPI for more then one device
  //set bitOrder, clockDivider and dataMode each time
  //SPI.setClockDivider(_clockDivider); 
  //SPI.setBitOrder(_bitOrder);
  //SPI.setDataMode(_dataMode);
  
  digitalWrite(_latchPin, LOW);
  SPI.transfer(_bitString);
  digitalWrite(_latchPin, HIGH); 
}

I guess the question now is, how can we make it not glitch the bus, because people ARE going to want to use multiple devices, and some won’t tolerate these glitches.

I’ll try to wrap this library up soon.

1 Like

I got a fix for the SPI glitch in the works… just capturing all of the scope plots to prove it works for all of the glitches then I will submit a pull request :wink:

EDIT: Pull request submitted… if you are interested in the fixes now check it out: https://github.com/spark/core-firmware/pull/73

so first of all, @BDub , fantastic all this work you are doing! it is very much appreciated, i am very impressed. let me know if there is anything i can do to help...

secondly, do you think there is a solution to fix it easily or do we need to wait for the fix on github?

Yeah there is an immediate fix… I just don’t call the SPI.setupstuff() in the spiSendOut() function anymore… but there is a ton of stuff I changed in the LiquidCrystal SPI library, so just hang tight I’m testing it now :smile:

EDIT: @korneel @Soulhuntre @Dave We’re live!

1 Like

@BDub,

Have you ever used a 74HC164 to interface with a LCD 16 x 2?

It’s also a Serial in parallel out but less pricey than a 75HC595…

http://sg.element14.com/nxp/74hc164n/ic-74hc-cmos-logic/dp/380623

I have not, but while it looks like half the price for DIP packages… the downside is it has no output latch, which means as you are shifting data into it, they are live on the outputs. This would make it basically impossible to create precise timing for a parallel input device… unless you only use this chip for all pins except for the Enable line on the LCD, and control the enable line separately. It might work then.

I would just pay the extra 50 cents though and go with the 595.

If you are making a product, the SMT chips for the 595 vs 164 are the same price… 10-11 cents so it’s better to go 595 in that case.