Hi everybody
i'm trying to store CC from TB-03 in eeprom and send it when I load a preset but it send values 127 even if i load an empty eeprom address
//#include <MIDI.h>
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
//MIDI_CREATE_DEFAULT_INSTANCE();
const uint8_t NOTE_OFF = 0x80;
const uint8_t NOTE_ON = 0x90;
const uint8_t KEY_PRESSURE = 0xA0;
const uint8_t CC = 0xB0;
const uint8_t PROGRAM_CHANGE = 0xC0;
const uint8_t CHANNEL_PRESSURE = 0xD0;
const uint8_t PITCH_BEND = 0xE0;
const unsigned long headerResendTime = 1000; // send a new header every second
const int Up_buttonPinChannel = 2;
const int Down_buttonPinChannel = 3;
int pinA = 5; // Connected to CLK on KY-040
int pinB = 6; // Connected to DT on KY-040
//int encoderSwitch = 4;
int pinALast;
int aVal;
boolean bCW;
// Variables will change:
int ChannelNumber = 1;
int up_buttonStateChannel = 0;
int up_lastButtonStateChannel = 0;
int down_buttonStateChannel = 0;
int down_lastButtonStateChannel = 0;
bool bPressChannel = false;
int oldPosition = 0;
int ProgramValue = 0;
/////////////////////////////////////////////////////////////////////////////////////
const int storeButtonPin = 4; // input button pin number
const unsigned long longPressThreshold = 2000; // the threshold (in milliseconds) before a long press is detected
const unsigned long debounceThreshold = 50; // the threshold (in milliseconds) for a button press to be confirmed (i.e. not "noise")
unsigned long buttonTimer = 0; // stores the time that the button was pressed (relative to boot time)
unsigned long buttonPressDuration = 0; // stores the duration (in milliseconds) that the button was pressed/held down for
boolean buttonActive = false; // indicates if the button is active/pressed
boolean longPressActive = false; // indicate if the button has been long-pressed
/////////////////////////////////////////////////////////////////////////////////////////
byte incomingByte;
byte CCNumber;
int TuningValue =0;
int CutoffValue =0;
int ResonanceValue =0;
int EnvmodValue =0;
int DecayValue =0;
int AccentValue =0;
int OverdriveValue =0;
int DelayTimeValue =0;
int DelayFeedbackValue =0;
int SlideValue =0;
boolean TuningCC = LOW;
boolean CutoffCC = LOW;
boolean ResonanceCC = LOW;
boolean EnvmodCC = LOW;
boolean DecayCC = LOW;
boolean AccentCC = LOW;
boolean OverdriveCC = LOW;
boolean DelayTimeCC = LOW;
boolean DelayFeedbackCC = LOW;
boolean SlideCC = LOW;
boolean CCmessage = LOW;
//byte ChannelNumber = 1;
/////////////////////////////////////////////////////////////////////////////////////////
const int TuningAddress = 0;
const int CutoffAddress = 1;
const int ResonanceAddress = 2;
const int EnvmodAddress = 3;
const int DecayAddress = 4;
const int AccentAddress = 5;
const int OverdriveAddress = 6;
const int DelayTimeAddress = 7;
const int DelayFeedbackAddress = 8;
const int SlideAddress = 9;
//////////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(31250);
// MIDI.begin (MIDI_CHANNEL_OMNI);
pinMode(storeButtonPin, INPUT_PULLUP); // set the button pin as an input
pinMode (pinA,INPUT);
pinMode (pinB,INPUT);
/* Read Pin A
Whatever state it's in will reflect the last position
*/
pinALast = digitalRead(pinA);
pinMode(storeButtonPin, INPUT_PULLUP);
pinMode( Up_buttonPinChannel , INPUT_PULLUP);
pinMode( Down_buttonPinChannel , INPUT_PULLUP);
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("CH:");
lcd.setCursor(3,0);
lcd.print(ChannelNumber);
lcd.setCursor(0,1);
lcd.print("PR:");
lcd.setCursor(3,1);
lcd.print(ProgramValue);
}
void loop() {
checkUp();
checkDown();
Channeldisplay();
checkIn(); // see if anything has arrived at the input
PCdisplay();
storeButton();
}
void Channeldisplay()
{
if( bPressChannel)
{
bPressChannel = false;
lcd.setCursor(3,0);
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print(ChannelNumber);
}
}
void PCdisplay()
{
aVal = digitalRead(pinA);
if (aVal != pinALast){ // Means the knob is rotating
// if the knob is rotating, we need to determine direction
// We do that by reading pin B.
if (digitalRead(pinB) != aVal) { // Means pin A Changed first - We're Rotating Clockwise
ProgramValue ++;
bCW = true;
} else {// Otherwise B changed first and we're moving CCW
bCW = false;
ProgramValue--;
}
if (ProgramValue<0){
ProgramValue=127;
}
if (ProgramValue>127){
ProgramValue=0;
}
lcd.setCursor(3,1);
lcd.print(" ");
lcd.setCursor(3,1);
lcd.print(ProgramValue);
}
pinALast = aVal;
}
////////////////////////////////////////////////////////////////////////////////////////
void checkUp()
{
up_buttonStateChannel = digitalRead(Up_buttonPinChannel);
if (up_buttonStateChannel != up_lastButtonStateChannel)
{
if (up_buttonStateChannel == LOW) {
bPressChannel = true;
// if the current state is HIGH then the button went from off to on:
ChannelNumber++;
if (ChannelNumber>16){ChannelNumber=1;}//passe de 16 à 1
// Serial.println("on");
// Serial.print("number of button pushes: ");
// Serial.println(ChannelNumber);
} else {
// if the current state is LOW then the button went from on to off:
//Serial.println("off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
up_lastButtonStateChannel = up_buttonStateChannel;
}
/////////////////////////////////////////////////////////////////////////////////////
void checkDown()
{
down_buttonStateChannel = digitalRead(Down_buttonPinChannel);
// compare the buttonState to its previous state
if (down_buttonStateChannel != down_lastButtonStateChannel) {
// if the state has changed, increment the counter
if (down_buttonStateChannel == LOW) {
bPressChannel = true;
// if the current state is HIGH then the button went from off to on:
ChannelNumber--;
if (ChannelNumber<1){ChannelNumber=16;}//passe de 1 à 16
// Serial.println("on");
//Serial.print("number of button pushes: ");
// Serial.println(ChannelNumber);
} else {
// if the current state is LOW then the button went from on to off:
//Serial.println("off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
down_lastButtonStateChannel = down_buttonStateChannel;
}
/////////////////////////////////////////////////////////////////////////////////////
void storeButton(){
// if the button pin reads LOW, the button is pressed (negative/ground switch)
if (digitalRead(storeButtonPin) == LOW)
{
// mark the button as active, and start the timer
if (buttonActive == false)
{
buttonActive = true;
buttonTimer = millis();
}
// calculate the button press duration by subtracting the button time from the boot time
buttonPressDuration = millis() - buttonTimer;
// mark the button as long-pressed if the button press duration exceeds the long press threshold
if ((buttonPressDuration > longPressThreshold) && (longPressActive == false))
{
longPressActive = true;
//Serial.print("Long press detected: ");
//Serial.println(buttonPressDuration);
////////////////////////////////////////////////////ICI STORE eeprom.write
ProgramWrite();
lcd.setCursor(7,1);
lcd.print("STORED!");
delay(1000);
lcd.setCursor(7,1);
lcd.print(" ");
}
}
// button either hasn't been pressed, or has been released
else
{
// if the button was marked as active, it was recently pressed
if (buttonActive == true)
{
// reset the long press active state
if (longPressActive == true)
{
longPressActive = false;
}
// we either need to debounce the press (noise) or register a normal/short press
else
{
// if the button press duration exceeds our bounce threshold, then we register a short press
if (buttonPressDuration > debounceThreshold)
{
//Serial.print("Short press detected: ");
//Serial.println(buttonPressDuration);
///////////////////////////////////////////////////ICI LOAD fonction eeprom.read
ProgramLoad();
lcd.setCursor(7,1);
lcd.print("LOADED!");
delay(1000);
lcd.setCursor(7,1);
lcd.print(" ");
}
// if the button press is less than our bounce threshold, we debounce (i.e. ignore as noise)
else
{
//Serial.print("Debounced: ");
//Serial.println(buttonPressDuration);
}
}
// reset the button active status
buttonActive = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////
void checkIn(){
static byte state=0; // state machine variable
//0 = command waiting
//1 = note waiting :
//2 = velocity waiting
if (Serial.available() > 0) {
// read the incoming byte:
byte incomingCC = Serial.read();
//Serial.write(incomingByte); // act as a MIDI THRU
switch (state){
case 0:
// look for a CC status-byte, our channel
if (incomingCC == ( 0xB0 | ChannelNumber)){ // read only one channel
CCmessage = HIGH;
state=1;
}
break;
case 1:
// get CC number
if(incomingByte < 128) {
CCNumber=incomingByte;
if (CCNumber == 104){
TuningCC = HIGH;
}
if (CCNumber == 74){
CutoffCC = HIGH;
}
if (CCNumber == 71){
ResonanceCC = HIGH;
}
if (CCNumber == 12){
EnvmodCC = HIGH;
}
if (CCNumber == 75){
DecayCC = HIGH;
}
if (CCNumber == 16){
AccentCC = HIGH;
}
if (CCNumber == 17){
OverdriveCC = HIGH;
}
if (CCNumber == 18){
DelayTimeCC = HIGH;
}
if (CCNumber == 19){
DelayFeedbackCC = HIGH;
}
if (CCNumber == 102){
SlideCC = HIGH;
}
state=2;
}
else {
state = 0; // reset state machine as this should be a note number
}
break;
case 2:
// get CC value
if(incomingByte < 128) {
if (TuningCC = HIGH){
TuningValue = incomingByte;
TuningCC = LOW;
}
if (CutoffCC = HIGH){
CutoffValue = incomingByte;
CutoffCC = LOW;
}
if (ResonanceCC = HIGH){
ResonanceValue = incomingByte;
ResonanceCC = LOW;
}
if (EnvmodCC = HIGH){
EnvmodValue = incomingByte;
EnvmodCC = LOW;
}
if (DecayCC = HIGH){
DecayValue = incomingByte;
DecayCC = LOW;
}
if (AccentCC = HIGH){
AccentValue = incomingByte;
AccentCC = LOW;
}
if (OverdriveCC = HIGH){
OverdriveValue = incomingByte;
OverdriveCC = LOW;
}
if (DelayTimeCC = HIGH){
DelayTimeValue = incomingByte;
DelayTimeCC = LOW;
}
if (DelayFeedbackCC = HIGH){
DelayFeedbackValue = incomingByte;
DelayFeedbackCC = LOW;
}
if (SlideCC = HIGH){
SlideValue = incomingByte;
SlideCC = LOW;
}
}
state = 0; // reset state machine to start
break;
}
}
}
void ProgramLoad()
{
TuningValue = EEPROM.read(TuningAddress +(ProgramValue*10));
CutoffValue = EEPROM.read(CutoffAddress +(ProgramValue*10));
ResonanceValue = EEPROM.read(ResonanceAddress +(ProgramValue*10));
EnvmodValue = EEPROM.read(EnvmodAddress +(ProgramValue*10));
DecayValue = EEPROM.read(DecayAddress +(ProgramValue*10));
AccentValue = EEPROM.read(AccentAddress +(ProgramValue*10));
OverdriveValue = EEPROM.read(OverdriveAddress +(ProgramValue*10));
DelayTimeValue = EEPROM.read(DelayTimeAddress +(ProgramValue*10));
DelayFeedbackValue = EEPROM.read(DelayFeedbackAddress +(ProgramValue*10));
SlideValue = EEPROM.read(SlideAddress +(ProgramValue*10));
sendMIDI(CC, ChannelNumber, 104,TuningValue );
sendMIDI(CC, ChannelNumber, 74,CutoffValue );
sendMIDI(CC, ChannelNumber, 71,ResonanceValue );
sendMIDI(CC, ChannelNumber, 12,EnvmodValue );
sendMIDI(CC, ChannelNumber, 75,DecayValue );
sendMIDI(CC, ChannelNumber, 16,AccentValue );
sendMIDI(CC, ChannelNumber, 17,OverdriveValue );
sendMIDI(CC, ChannelNumber, 18,DelayTimeValue );
sendMIDI(CC, ChannelNumber, 19,DelayFeedbackValue );
sendMIDI(CC, ChannelNumber, 102,SlideValue );
}
//////////////////////////////////////////////////////////////////////////////////////////
void ProgramWrite()
{
EEPROM.update(TuningAddress +(ProgramValue*10), TuningValue);
EEPROM.update(CutoffAddress +(ProgramValue*10), CutoffValue);
EEPROM.update(ResonanceAddress +(ProgramValue*10), ResonanceValue);
EEPROM.update(EnvmodAddress +(ProgramValue*10), EnvmodValue);
EEPROM.update(DecayAddress +(ProgramValue*10), DecayValue);
EEPROM.update(AccentAddress +(ProgramValue*10), AccentValue);
EEPROM.update(OverdriveAddress +(ProgramValue*10), OverdriveValue);
EEPROM.update(DelayTimeAddress +(ProgramValue*10), DelayTimeValue);
EEPROM.update(DelayFeedbackAddress +(ProgramValue*10), DelayFeedbackValue);
EEPROM.update(SlideAddress +(ProgramValue*10), SlideValue);
}
////////////////////////////////////////////////////////////////////
void sendMIDIHeader(uint8_t header) {
static unsigned long lastHeaderTime = millis();
static uint8_t runningHeader = 0;
if (header != runningHeader // If the new header is different from the previous ETAT COURANT réduit les données donc accélère
|| (millis() - lastHeaderTime)
> headerResendTime) { // Or if the last header was sent more than 1 s ago ne renvoie pas l'octet de statut tant que celui-ci ne change pas
Serial.write(header); // Send the status byte over Serial
runningHeader = header; // Remember the new header
lastHeaderTime = millis();
}
}
///////////////////////////////////////////////////////////////////////////////////////
void sendMIDI(uint8_t messageType, uint8_t channel, uint8_t data1, uint8_t data2) {
if (messageType == NOTE_OFF) { // Replace note off messages
messageType = NOTE_ON; // with a note on message
data2 = 0; // with a velocity of zero.
}
channel--; // Decrement the channel, because MIDI channel 1
// corresponds to binary channel 0
uint8_t statusByte = messageType | channel; // Combine the messageType (high nibble)
// with the channel (low nibble)
// Both the message type and the channel
// should be 4 bits wide
statusByte |= 0b10000000; // Set the most significant bit of the status byte
data1 &= 0b01111111; // Clear the most significant bit of the data bytes
data2 &= 0b01111111;
sendMIDIHeader(statusByte); // Send the header over Serial, using running status
Serial.write(data1); // Send the data bytes over Serial
Serial.write(data2);
}
void sendMIDI(uint8_t messageType, uint8_t channel, uint8_t data) {
channel--; // Decrement the channel, because MIDI channel 1
// corresponds to binary channel 0
uint8_t statusByte = messageType | channel; // Combine the messageType (high nibble)
// with the channel (low nibble)
// Both the message type and the channel
// should be 4 bits wide
statusByte |= 0b10000000; // Set the most significant bit of the status byte
data &= 0b01111111; // Clear the most significant bit of the data byte
sendMIDIHeader(statusByte); // Send the header over Serial, using running status
Serial.write(data); // Send the data byte over Serial
}
Where the problem could be?
Thanks