That solved it. Got a good SPI signal coming out. DotStar is not successfully reading it but I think that's because I am trying without level shifters. I'll get some and then maybe all will be well. Thanks again for your excellent help.
JohnBuschert

- Apr 12, 2024
- Joined Aug 1, 2022
- 5 discussions
- 13 posts
That looks like what I want, but where is PinmuxUtil defined? The compiler does not recognize it. I've tried including everything you did in that code and it still does not recognise the function. Is this a recent addition to one of the libraries?
Thanks Giulio! You were right. I had run the config-pin lines earlier but in the meantime I had cycled the power and these config settings evidently are not saved. And thanks for your code, I'll take a look at it.
Is there a way to do this or a place to put commands like these that will get executed automatically on startup or when a particular program is run? I was hoping to have the programs I'm writing run automatically on startup but this issue will require a few commands to be run every time.
Thanks again for your great help.
I just looked more carefully and I the MOSI line is not even showing the data. It is just a poor copy of the clock signal. The first two bytes are supposed to be 0xff and 0x22 but they just look like the clock. So the line is probably not getting any driving from the Bela and is just picking up the clock by stray capacitance. So the question still is, why no MOSI signal?
I'm trying to use SPI to control some DotStar light strips and SPI does not seem to be working correctly. I'm running the example straight from the library in the Bela IDE. I get a good clock signal but the MOSI data line looks like a weak bad connection. Here's a scope picture.
I get the same result with two different Bela Minis's so I don't think this is a bad or damaged Bela. I tried adding a pinMode for that pin which is also a Bela Digital line #10. But setting it to Output completely eliminated the signal. Setting it to Input gives the same result as shown. (I think it's the default). Any ideas?
OK, there probably is not a simple hard maximum for these so I've changed the wording from "max 250mA" to "250mA available". I've updated the diagram at the top of this post also to reflect all these changes so if someone sees it and copies it without scrolling down they get the correct info.
- Edited
Thanks Giulio. I changed the label on that 5V supply to "Ext/USB" to better reflect the source and the current as "250mA or more depending on the source" as per your information. I've attached the latest version of the diagram in png format. I also corrected the D10 label. I can't seem to upload pdf to this forum, is there a trick to that?
I just looked more closely and found the value of the series resistor on the weak 5V line. It is 100 ohms. I'm still eager to know how much current is really available on the 5V regulated line from BBB.
- Edited
Here is a hover free pin diagram with other useful hardware info on it. LFSaw was working on one back in August but it was the wrong orientation. I wanted one to post on my wall, so I made my own and here it is for anyone to use. I changed the color scheme for many of the pins because the scheme used in the IDE hover diagram is truly bizarre (ground is red!!??). LFSaw had a good idea to put other useful hardware info on the diagram which I have also done. It's hard to find some of this and I'm still unsure of a couple items so here are my questions:
1. The BBB specs say that the 5V supply has 250mA available. Bela info repeats that. But the Bela board draws some current for itself so there can't still be 250mA left. Does anyone know how much is realy available from the regulated 5V line on Bela to power user circuitry?
2. The "weak" 5V line has a resistor in series that is named as 100 ohms in one place and 220 ohms in another. I can see no value listed on the schematic.
Is there any other useful hardware information that should be included? I'd be glad to make further revisions.- Edited
Thanks Giulio.
You were enormously helpful! I've been delayed by many other things. But with your fixes I finally got it all working. Now I have a library that can be used to get Bela to talk to most simple 16x2 or 20x4 character LCD displays such as this one I'm using.
This is a Sunfounder 20x4 display I got on Amazon for $12
Here is a link to my github LCD_I2C folder for anyone that wishes to use this library or give me advice.And here is the header file for quick reference:
/* LCD_I2C.h version 1.0 2022-10-28 LCD w I2C writing routines header file This library allows Bela to write to a 20x4 LCD display via I2C It has been tested and works with the Sunfounder I2C LCD 2004 It should work with most 16x2 or 20x4 displays that have an I2C backpack Specifically those using the HDD44780 and PCF8574T chips which seem to be common. It does the same thing as the LiquidCrystal_I2C library for Arduino and other things but instead of just encapsulating that yet one more time, I rewrote it but included most of the LiquidCrystal_I2C commands for compatibility. */ #include <I2c.h> #include <string> class LCD_I2C : public I2c { public: LCD_I2C (int bus, int address); // Constructor. For Bela the usual I2C bus is 1, the I2C address depends on your device // standard commands in common with Liquid_Crystal_I2C library void clear(); // clears the display void home(); // returns cursor to row 0 col 0 void setCursor(uint8_t row, uint8_t col); // sets cursor at row(0-3), col(0-20) or whatever size you have void write(std::string text); // writes text starting at cursor's location void noDisplay(); void display(); void noBlink(); void blink(); void noCursor(); void cursor(); void noBacklight(); void backlight(); void begin(); // unneeded null function kept only for compatibilty // new commands void setCursorWrite(uint8_t row, uint8_t col, std::string text); // sets cursor to coords and then writes text void mode(int backlight, int display, int cursor, int blink); // 1 or 0 sets all these on or off /* not yet implemented from LiquidCrystal_I2C library scrollDisplayLeft scrollDisplayRight printLeft printRight ledftToRight RightToLeft shiftIncrement shiftDecrement autoScroll noAutoScroll createChar printRight init oled_init */ private: // Lower level commands that differ from LiquidCrystal_I2C void sendChar(uint8_t); void sendCommand(uint8_t hiNib, uint8_t loNib); void sendNibble(uint8_t nib, uint8_t rs); void transmit(uint8_t byte); uint8_t buf[2] = {0,0}; // buffer for characters pass to I2c write (it wants an array, maybe could have been a pointer) uint8_t nibble =0; uint8_t hiNib = 0; uint8_t loNib = 0; int gbacklight = 1; // default value when started int gdisplay = 1; int gcursor = 1; int gblink = 1; uint8_t homeAddress[4] = {0x00, 0x40, 0x14, 0x54}; // beginning address of each line for 2 or 4 line displays };
Bela people,
I'm trying to use a small several line LCD display which has a backpack that communicates via I2C. So I'm using the I2c.h library and I wrote the beginnnings of another library combining the needed LCD commands from arduino examples with the required I2c parts that I modeled after the few examples I could find of Bela programs using I2c. It now compiles and runs with no errors but sends nothing on the I2C bus lines. I checked the address using i2cdetect and when I run that check I can see activity on the bus lines but when I run my program see no activity on the bbus lines and so nothing happens on the display.I'm not very experienced with C++ so any ideas or help would be very welcome. Here is the entirety of the code:
SunfounderLCD.h
#include <I2c.h> #include <string> class SF_LCD : public I2c { public: SF_LCD (int bus, int address); // Constructor. brings in the bus and address void clear(); void setupLCD(); // sets up things with display, cursor and blink all on void writeLCD(std::string text); private: };
SunfounderLCD.cpp
#include <iostream> #include <SunfounderLCD.h> I2c myI2c; // creates an instance of the I2c class // initialize LCD SF_LCD::SF_LCD (int bus, int address) { // constructor for the LCD object myI2c.initI2C_RW(bus, address, 0); usleep(2000); } // clear LCD display needs to send command 0x01 void SF_LCD::clear() { uint8_t buf[2] = {0x01, 0}; write(i2C_file, buf, 1); usleep(2000); } // setup LCD with display on, cursor on, blink on, needs to send 0x0F void SF_LCD::setupLCD() { uint8_t buf[2] = {0x0F, 0}; write(i2C_file, buf, 1); usleep(2000); } // write text to LCD void SF_LCD::writeLCD(std::string text) { int len = text.length(); char* buf2 = &text[0]; write(i2C_file, buf2, len); }
render.cpp
#include <Bela.h> #include <SunfounderLCD.h> SF_LCD myDisplay(1, 0x27); // myDisplay I2C is on bus=1 addr=0x27 bool setup(BelaContext *context, void *userData) { myDisplay.clear(); myDisplay.setupLCD(); myDisplay.writeLCD("Hello!"); return true; } void render(BelaContext *context, void *userData) { } void cleanup(BelaContext *context, void *userData) { }
- Edited
I've seen a few people wondering about using soundfonts on Bela. I found an easy way to do this that works very well. The key is to use TinySoundFont, a soundfont synthesizer written by Bernhard Schelling. It's a single header file written in C/C++ with zero dependencies! It was easy to incorporate into Bela and it worked almost immediately when I first tried it. The only downside I see is that the he did not implement a few more advanced features and he is no longer working on it. But what he created has worked very well for me.
[TinySoundFont]<https://github.com/schellingb/TinySoundFont>
At the beginning of the tsf.h header file is a long comments section explaining how to use it and giving examples. My code is derived from those examples and I list all the pieces you need to use it with Bela below.
The first part goes at the beginning of the Bela program (before Setup)
You need to set the soundfont filename to whatever soundfont you wish to use and upload that soundfont file into the resources section of your project. Also set the preset to whatever preset you wish to use from the soundfont.// Setting up Tiny Sound Font synthesizer --- #define TSF_IMPLEMENTATION #include "tsf.h" int max_voices = 32; // This affects the number of notes it can keep up with. int samplerate = 44100; float tsf_gain_db = 10; // tsf output gain in dB float tsf_bufferptr[64]; // buffer for 160 samples const char *filename = "Piano.sf2"; // soundfont filename const char *presetNames[25]; int preset = 2; // preset from the soundfont (often 0 if there is only one preset) tsf* fontptr;
This next part goes in the setup section
// setup section for tsf ----- fontptr = tsf_load_filename(filename); tsf_reset(fontptr); tsf_set_max_voices(fontptr, max_voices); tsf_set_volume(fontptr, 1.0); tsf_set_output(fontptr, TSF_MONO, samplerate, tsf_gain_db);
Then in the Render section, in response to inputs whenever you decide to start a note you can use the following. There are many other commands available as well, this is just the simplest starting point. You need to understand that this just tells tsf that you want a note to stop or start, so the next time it is called to do rendering is when these changes will take effect.
tsf_note_off_all(fontptr); // turn off any previous notes tsf_note_on(fontptr, preset, pitch, velocity); // start a new note: pitch is midi note number, velocity is 0-1.0
Lastly this section goes at the end of the Render section (after the close of the n loop over all the frames but before the close of Render) so it is only executed once per render call. I tried calling tsf_render for each sample but that took too much time and Bela complained of mode switches and it sounded terrible. But doing with one call per block has worked very well.
// Call tsf to render a block of samples in one call and then write them all to Bela's audio output. int samples = context->audioFrames; // number of audio samples in a block tsf_render_float(fontptr, tsf_bufferptr, samples, 0); // tsf outputs block of samples into its buffer for (int i2 = 0; i2 < context->audioFrames; i2++){ // copy from tsf buffer to Bela output float output = tsf_bufferptr[i2]; audioWrite(context, i2, 0, output); // 0=left 1=right audioWrite(context, i2, 1, output); // 0=left 1=right }
This worked for me. I hope it can be useful to someone else.
-John- Edited
I'm new to this forum, I've been working on a long term project with Bela for some time with a few students and I have wished for a better diagram of the hardware and software I/O timing on Bela. I keep adding to it as I learn more about the system and think of better arrangements. The main idea is to have time flow from left to right and have hardware at the top and software at the bottom. Attached is my latest version. I'd be glad for corrections, criticisms, suggestions or any comments. It does not show the analog output and I'm aware that the audio output should be shown and described as going through a DAC before the output amp. Apart from that, Is this correct? Is it of any use to any of you?
John