Open benwadub opened 3 years ago
What are you having trouble with? The TimeDisplay
class inherits from the Arduino Printable
class, so you can just do something like
Adafruit_ILI9341 tft = (...);
MCU::TimeDisplay timedisplay = {};
...
tft.print(timedisplay);
You can also use the getText()
and getCharacterAt()
methods, see the documentation for more details.
As you know I started arduino with your library so when I have to use something not implemented by you all become difficult :-) I didn’t know at all where to start and didn’t began to writ anything, I ll try to make a first test this evening
// Time display
MCU::TimeDisplayDisplay timedisplaydisplay = {};
// position (0, 0), font size (1)
tft.print (timedisplay), {0, 0}, 1, ILI9341_WHITE,
};
when I try it I get:
controleur_BEN_and_ED_ableton1_2_touch_avec_display_et_boutons:315: error: could not convert '
so my code compile now but time display doesn't show on screen, do you know what I missed?
#include <Control_Surface.h>
#include <Encoder.h> // Include the Encoder library.
//#include <name.c>
#include <SPI.h>
#include <ILI9341_t3.h>
//USBDebugMIDI_Interface midi = 115200; // enlever les // en début de ligne pour entrer en mode debug usb et voir dans le panneau de control si vos controler envoient bien les infos
//auto &serial = Serial1;// Selectionne le port série à utiliser remplacer par serial pour une arduino
//SerialMIDI_Interface<decltype(serial)> midi = {serial, MIDI_BAUD};// démarre une interface midi serial au midi baud rate par defaut
USBMIDI_Interface usbmidi;// enlever les / en debut de ligne pour activer l'interface usb, penser à désactiver l'interface série(din)
//HardwareSerialMIDI_Interface midiser = Serial1;
#include "TouchScreen.h"
// These are the four touchscreen analog pins
#define YP 23 // must be an analog pin, use "An" notation!
#define XM 22 // must be an analog pin, use "An" notation!
#define YM 4 // can be a digital pin
#define XP 5 // can be a digital pin
// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
#define MINPRESSURE 10
#define MAXPRESSURE 1000
// The display uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
#define rst -1
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 360);
// Size of the color selection boxes and the paintbrush size
#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;
// -------------------------- MIDI Input Elements --------------------------- //
// ========================================================================== //
/*
Define all elements that listen for MIDI messages.
*/
MCU::TimeDisplay timedisplay = {};
// Play / Record
CCValue play = {{103, CHANNEL_1}};
CCValue record = {{104, CHANNEL_1}};
void setup() {
tft.begin();
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin(); // initialise la library surface de control
// Display a splash screen for five seconds
//tft.fillScreen(ILI9341_BLACK),
tft.print (timedisplay),timedisplay, (0, 0, 1, ILI9341_WHITE);
/* tft.drawXBitmap(0, 0,
XBM::logo.bits,
XBM::logo.width,
XBM::logo.height,
ILI9341_WHITE);
display.display();
delay(5000);
*/
}
void loop() {
Control_Surface.loop(); // Update the Control Surface
usbmidi.update();
}```
timedisplay, (0, 0, 1, ILI9341_WHITE);
This expression has no effect. Please enable all compiler warnings in the IDE, it should warn you about things like that.
You really need to get out of the habbit of randomly adding or removing brackets and other punctuation until your code compiles. I highly recommend following a C++ tutorial/book, because I can fix individual problems with your code, but I cannot teach you how to program.
Please see the examples that come with the ILI9341 library to learn how to print text to the display, e.g. https://github.com/PaulStoffregen/ILI9341_t3/blob/effb156ef9bf94d11ec12c4b8f122f3b35d0e1e7/examples/onoffbutton/onoffbutton.ino#L50-L53:
#include <Control_Surface.h>
#include <SPI.h>
#include <ILI9341_t3.h>
USBMIDI_Interface usbmidi;
// The display uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
#define rst -1
ILI9341_t3 tft(TFT_CS, TFT_DC);
// This timedisplay just listens to incoming MIDI messages,
// it has nothing to do with any physical displays connected to
// the Teensy.
MCU::TimeDisplay timedisplay = {};
void setup() {
tft.begin();
tft.fillScreen(ILI9341_BLACK),
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin();
}
void loop() {
tft.setCursor(0, 0);
tft.setTextSize(1);
tft.setTextColor(ILI9341_WHITE);
tft.print(timedisplay);
Control_Surface.loop();
}
The code above is untested, because I don't have the necessary hardware or libraries installed, but it should given you a rough idea of what you need to do to get it working. If you're using the new-input
branch, you can detect if the content of the time display changed using the MCU::TimeDisplay::getDirty()
and clearDirty()
methods, otherwise, it'll re-draw the display on each iteration of the loop()
, which is probably not what you want.
thanks that nearly work! I begin understanding MCU! all is clear now with things that listen midi!! i ll check if I find the documentation for get dirty and clean dirty, I think it s something to clear the screen to avoid the character becoming unreadable after few loops!
getDirty()
has nothing to do with the displays per se, it's just a way of detecting changes. See https://tttapa.github.io/Control-Surface-doc/new-input/Doxygen/df/d69/classMCU_1_1TimeDisplay.html#a67459e7b1758df918954df57cfec7384.
ok so I just have to write cpp MCU::TimeDisplay timedisplay = {}; MCU::TimeDisplay::clearDirty(),
and it will get change and clean them before redraw that s the way I understand it
MCU::TimeDisplay::clearDirty()
You can't write that, clearDirty()
is a non-static member function, you have to invoke it against an instance of the MCU::TimeDisplay
class. Again, there's no point in trying to use these functions without first understanding the basics of C++ functions, namespaces and classes.
When the timedisplay
object receives a MIDI message that changes the text of the display, it sets the “dirty” flag. You can query that flag using the MCU::TimeDisplay::clearDirty()
method, calling timedisplay.getDirty()
if that method returns true
, you know that you have to re-draw the text to the display. Finally, you clear the “dirty” flag again to acknowledge the change, and so you can detect the next change.
Thanks! I ll try to find a good book to learn basics to understand better how the library and c++ works
Getting a book is a good idea, but if that's not an investment you want to make, you could try https://www.learncpp.com. I haven't followed it myself, but I've heard good things about it, and it seems to covers pretty much everything you need to know.
You don't need to read and understand all of it, some parts are pretty specific or don't really apply to microcontrollers, but you do need a firm understanding of things like statements, expressions, variables, scope, lifetime, functions, classes, initialization, etc. Otherwise programming will feel more like a guessing game, which is not an efficient strategy.
yes thanks!! I really want to learn and understand what id do and now that I really need specific things to ad to my controller I have to learn the basics!
i ll wait that you put exemple with the dirty things, Doxygen files are a big mystery for me!! I began reading the site you gave me and already learnt few things! thanks!
Here's an example: https://tttapa.github.io/Control-Surface-doc/new-input/Doxygen/d0/d6c/Pitch-Bend-Value_8ino-example.html
It uses PBValue
instead of TimeDisplay
, but the only real difference is that the former listens for MIDI Pitch Bend messages, and the latter listens for MIDI MCU Time Display messages. It also prints to the serial port instead of a display, but once you figure out how the Adafruit ILI9341 examples work, that shouldn't be an issue either.
hi Pieter, i finaly find time to come back to the ili9341 I can now see the time display on the ili9341 using this code
#include <Control_Surface.h>
#include <SPI.h>
#include <ILI9341_t3.h>
USBMIDI_Interface usbmidi;
Bank<4> bank(2); // Create a new bank with two tracks per bank
// The display uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
#define rst -1
ILI9341_t3 tft(TFT_CS, TFT_DC);
// This timedisplay just listens to incoming MIDI messages,
// it has nothing to do with any physical displays connected to
// the Teensy.
MCU::TimeDisplay timedisplay = {};
void setup() {
tft.begin();
tft.fillScreen(ILI9341_BLACK),
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin();
}
void loop() {
tft.setCursor(0, 0);
tft.setTextSize(4);
tft.setTextColor(ILI9341_WHITE);
//tft.print(timedisplay);
if (timedisplay.getDirty()) {
// Print it
tft.print(timedisplay);
// Clear the dirty flag to acknowledge the change
timedisplay.clearDirty();
tft.fillScreen(ILI9341_BLACK);
tft.print(timedisplay);
}
Control_Surface.loop();
}
i had to filscreen in the loop to avoid the problem of my number on the screen that continuously overwrite on the precedent it s not really nice to see because the numbers seems to scroll on the screen but for a beginner like me it s a cool thing for the moment just to see it working! i ll now try to investigate how to show mute state on the ili9341 for the moment I get an error 👍
Arduino : 1.8.13 (Mac OS X), TD: 1.53, Carte : "Teensy 4.0, Serial + MIDI, 600 MHz, Faster, US English"
In file included from /Users/benoitparisot/Documents/Arduino/libraries/Control-Surface-new-input/src/Control_Surface.h:91:0,
from /Users/benoitparisot/Documents/Arduino/test_timedisplay/test_timedisplay.ino:1:
/Users/benoitparisot/Documents/Arduino/libraries/Control-Surface-new-input/src/MIDI_Inputs/MCU/VU.hpp:188:7: warning: 'CS::MCU::VU' has a field 'CS::MCU::VU::decayTimer' whose type uses the anonymous namespace
class VU : public MatchingMIDIInputElement<MIDIMessageType::CHANNEL_PRESSURE,
^
test_timedisplay:18: error: 'mute' was not declared in this scope
{tft.print, mute[0], XBM::mute_10B, {14, 50}, ILI9341_WHITE},
^
test_timedisplay:19: error: 'mute' was not declared in this scope
{tft.print, mute[1], XBM::mute_10B, {14 + 64, 50}, ILI9341_WHITE},
^
test_timedisplay:20: error: could not convert '{tft.Print::print, <expression error>, CS::XBM::mute_10B, {14, 50}, 65535}' from '<brace-enclosed initializer list>' to 'CS::BitmapDisplay<>'
};
^
test_timedisplay:20: error: could not convert '{tft.Print::print, <expression error>, CS::XBM::mute_10B, {78, 50}, 65535}' from '<brace-enclosed initializer list>' to 'CS::BitmapDisplay<>'
'mute' was not declared in this scope
Ce rapport pourrait être plus détaillé avec
l'option "Afficher les résultats détaillés de la compilation"
activée dans Fichier -> Préférences.
with the code
#include <Control_Surface.h>
#include <SPI.h>
#include <ILI9341_t3.h>
USBMIDI_Interface usbmidi;
Bank<4> bank(2); // Create a new bank with two tracks per bank
// The display uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
#define rst -1
ILI9341_t3 tft(TFT_CS, TFT_DC);
// This timedisplay just listens to incoming MIDI messages,
// it has nothing to do with any physical displays connected to
// the Teensy.
MCU::TimeDisplay timedisplay = {};
BitmapDisplay<> muteDisp[] = {
{tft.print, mute[0], XBM::mute_10B, {14, 50}, ILI9341_WHITE},
{tft.print, mute[1], XBM::mute_10B, {14 + 64, 50}, ILI9341_WHITE},
};
void setup() {
tft.begin();
tft.fillScreen(ILI9341_BLACK),
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin();
}
void loop() {
tft.setCursor(0, 0);
tft.setTextSize(4);
tft.setTextColor(ILI9341_WHITE);
//tft.print(timedisplay);
if (timedisplay.getDirty()) {
// Print it
tft.print(timedisplay);
// Clear the dirty flag to acknowledge the change
timedisplay.clearDirty();
tft.fillScreen(ILI9341_BLACK);
tft.print(timedisplay);
}
Control_Surface.loop();
}
i ll try to understand what it mean!
test_timedisplay:18: error: 'mute' was not declared in this scope {tft.print, mute[0], XBM::mute_10B, {14, 50}, ILI9341_WHITE}, ^
You're trying to use a variable named mute
, but you never declared a variable mute
. Have a look at the OLED examples, they contain a declaration (and definition) of mute
.
#include <Control_Surface.h>
#include <SPI.h>
#include <ILI9341_t3.h>
USBMIDI_Interface usbmidi;
// The display uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
#define rst -1
ILI9341_t3 tft(TFT_CS, TFT_DC);
// This timedisplay just listens to incoming MIDI messages,
// it has nothing to do with any physical displays connected to
// the Teensy.
MCU::TimeDisplay timedisplay = {};
Bank<4> bank(2); // Create a new bank with two tracks per bank
NoteValue play = {MCU::PLAY};
NoteValue record = {MCU::RECORD};
// Mute
Bankable::NoteValue<4> mute[] = {
{bank, MCU::MUTE_1},
{bank, MCU::MUTE_2},
};
BitmapDisplay<> muteDisp[] = {
{tft.print, mute[0], XBM::mute_10B, {14, 50}, ILI9341_WHITE},
{tft.print, mute[1], XBM::mute_10B, {14 + 64, 50}, ILI9341_WHITE},
};
void setup() {
tft.begin();
tft.fillScreen(ILI9341_BLACK),
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin();
}
void loop() {
tft.setCursor(0, 0);
tft.setTextSize(4);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
//tft.setTextColor(ILI9341_WHITE);
//tft.print(timedisplay);
if (timedisplay.getDirty()) {
// Print it
tft.print(timedisplay);
// Clear the dirty flag to acknowledge the change
timedisplay.clearDirty();
}
BitmapDisplay<> muteDisp[] = {
{tft.print, mute[0], XBM::mute_10B, {14, 50}, ILI9341_WHITE},
{tft.print, mute[1], XBM::mute_10B, {14 + 64, 50}, ILI9341_WHITE},
};
Control_Surface.loop();
}```
I got the same problem with the mute declared like this, maybe those print you wrote are related to your display interface that I don t use cause I use the ili9341?
may I have to try to make a display interface for the ili9341 to make it work?
hi @tttapa I try to make the adapter for the ili9341 here is how I made it, I use the Paul 's library for ili9341 found here https://github.com/PaulStoffregen/ILI9341_t3 here is my adapter
#pragma once
#include <ILI9341_t3.h>
#include <Display/DisplayInterface.hpp>
BEGIN_CS_NAMESPACE
/**
* @brief This class creates a mapping between the Adafruit_SSD1306 display
* driver and the general display interface used by the Control Surface
* library.
*/
class ILI9341_DisplayInterface : public DisplayInterface {
protected:
ILI9341_DisplayInterface(ILI9341_t3 &display) : tft(display) {}
public:
/// Clear the frame buffer or clear the display.
void clear() override { tft.fillScreen(ILI9341_BLACK)(); }
/// Draw a custom background.
void drawBackground() override = 0;
/// Write the frame buffer to the display. If your display library writes to
/// the display directly, without a display buffer in RAM, you can leave
/// this function empty.
void display() override { tft.begin(); }
/// Paint a single pixel with the given color.
void drawPixel(int16_t x, int16_t y, uint16_t color);
/// Set the text color.
void setTextColor(uint16_t c);
/// Set the text size.
void setTextSize(uint8_t s);
/// Set the cursor position.
void setCursor(int16_t x, int16_t y);
/**
* @brief Write a character to the display.
*
* @see setCursor
* @see setTextSize
* @see setTextColor
*/
virtual size_t write(uint8_t);
/// Draw a line between two points.
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
/// Draw a vertical line.
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
/// Draw a horizontal line.
void drawFastHLine(int16_t x, int16_t y, int16_t h, uint16_t color);
/// Draw a bitmap to the display.
void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);
protected:
ILI93341_t3 &display;
};
END_CS_NAMESPACE
but when I use it in my code I got the error aft was not declared I find it strange as I include the library in the adapter do I have to modify an other file in the display interfaces? here is the code
#include <Control_Surface.h>
USBMIDI_Interface usbmidi;
#include <SPI.h>
#include <Display/DisplayInterfaces/DisplayInterfaceSILI9341.hpp>
#include <ILI9341_t3.h>
// The display uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
#define rst -1
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
//ILI9341_t3 tft(TFT_CS, TFT_DC);
//extern uint8_t play_bitmap[];
// This timedisplay just listens to incoming MIDI messages,
// it has nothing to do with any physical displays connected to
// the Teensy.
MCU::TimeDisplay timedisplay = {};
NoteValue play {MCU::PLAY};
void setup() {
Serial.begin(9600);
tft.begin();
tft.fillScreen(ILI9341_BLACK),
Serial.begin(9600);
// Correct relative mode for MCU rotary encoders
RelativeCCSender::setMode(MACKIE_CONTROL_RELATIVE);
Control_Surface.begin();
}
void loop() {
tft.setRotation(1);
tft.setCursor(0, 0);
tft.setTextSize(3);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
if (timedisplay.getDirty()) {
// Print it
tft.print(timedisplay);
// Clear the dirty flag to acknowledge the change
timedisplay.clearDirty();
//tft.fillScreen(ILI9341_BLACK);
//tft.print(timedisplay);
}
tft.setCursor(0, 60);
tft.setTextSize(3);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
if (play.getDirty()) {
/*tft.drawBitmap(65, 70, play_bitmap, 195, 146,ILI9341_RED);
void drawBitmap(int16_t x, int16_t y,
const uint8_t play_bitmap, int16_t w, int16_t h, uint16_t color) {
int16_t i, j, byteWidth = (w + 7) / 8;
uint8_t byte;
for(j=0; j<h; j++) {
for(i=0; i<w; i++) {
if(i & 7) byte <<= 1;
else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8);
if(byte & 0x80) tft.drawPixel(x+i, y+j, color);
}*/
// Print it
//tft.println("play");
// Clear the dirty flag to acknowledge the change
play.clearDirty();
}
Control_Surface.loop();
}```
I got the error tft was not declared
That's because you didn't declare it. You only declared display
, not tft
:
protected: ILI93341_t3 &display; };
Either rename that member variable to tft
, or replace tft
by display
in the rest of the code.
hi everyone, does someone as already wrote a code to use the mcu of the control surface to print on an ili9341?