I have a problem with a code implementation for SDCC and the C wrapper.
The thing I want to do is a “wind wheel” for Traktor with an encoder. The wind funktion in Traktor is working in the following manner:
* When deck is paused, and aMIDI input of 40Hex (64= 128/2 = half range) there is no wind.
* From 64 down to 0 the deck winds faster and faster in reverse.
* From 64 up to 127 the deck winds faster and faster in forward direction.
So I want my “Wind encoder” to work as follow:
* When I turn it slow clockwise I want to send 64 + “little deviation” i.e 65 or 66.
* The faster I turn the encoder the bigger values are outputet, up to 127.
* Same thing when turning counterclockwise, but from 64 downto 0..
Thougt solution:
* Use a timer to increase a variable every time the timer function is called.
* Then when the ENC_NotifyChange function is called I check the counter variable how many ticks it has gone since the last call of ENC_NotifyChange.
* Then calculate the deviation from 64 and send it to Traktor.
* Finally set the counter variable to zero.
Here is the code :
/*
* C example
*
* ==========================================================================
*
* Copyright (C) 2004 Thorsten Klose (tk@midibox.org)
*
* ==========================================================================
*
* This file is part of a MIOS application
*
* This application is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with This application; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ==========================================================================
*/
#include "cmios.h"
//#include <pic18f452.h>
unsigned int deviation;
unsigned int value;
unsigned int timer_counter;
unsigned int counts;
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after startup to initialize the
// application
/////////////////////////////////////////////////////////////////////////////
void Init(void)
{
timer_counter = 0;
// If 1 pulse/sec is minimum resolution, timer_counter should have a
// frequency of 64 Hz = 15,625ms
// calculate the required number of clocks for this period:
// clocks = period / 400 nS = 15,625 mS / 400 nS = 39062
MIOS_TIMER_Init(4,39062);
// define number of shift registers
MIOS_SRIO_NumberSet(16);
MIOS_AIN_Muxed();
MIOS_AIN_NumberSet(8);
MIOS_AIN_DeadbandSet(8);
// update frequency of SRIO chain
MIOS_SRIO_UpdateFrqSet(1); // ms
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS in the mainloop when nothing else is to do
/////////////////////////////////////////////////////////////////////////////
void Tick(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// This function is periodically called by MIOS. The frequency has to be
// initialized with MIOS_Timer_Set
/////////////////////////////////////////////////////////////////////////////
void Timer(void)
{
timer_counter++;
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when the display content should be
// initialized. Thats the case during startup and after a temporary message
// has been printed on the screen
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Init(void)
{
// clear screen
MIOS_LCD_Clear();
}
/////////////////////////////////////////////////////////////////////////////
// This function is called in the mainloop when no temporary message is shown
// on screen. Print the realtime messages here
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Tick(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a complete MIDI event has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2)
{
// print received MIDI event
MIOS_LCD_Clear();
MIOS_LCD_PrintCString("Received:");
MIOS_LCD_CursorSet(0x40);
MIOS_LCD_PrintHex2(evnt0);
MIOS_LCD_PrintHex2(evnt1);
MIOS_LCD_PrintHex2(evnt2);
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has been received
// which has been specified in the MIOS_MPROC_EVENT_TABLE
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyFoundEvent(unsigned entry, unsigned char evnt0, unsigned char evnt1, unsigned char envt2)
{
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has not been completly
// received within 2 seconds
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyTimeout(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI byte has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedByte(unsigned char byte)
{
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS before the shift register are loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Prepare(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after the shift register have been loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Finish(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an button has been toggled
// pin_value is 1 when button released, and 0 when button pressed
/////////////////////////////////////////////////////////////////////////////
void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value)
{
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an encoder has been moved
// incrementer is positive when encoder has been turned clockwise, else
// it is negative
/////////////////////////////////////////////////////////////////////////////
void ENC_NotifyChange(unsigned char encoder, unsigned char incrementer)
{
counts = timer_counter;
//Over 1 sec from last function call ?
if (counts >= 64)
counts = 64;
//Calculate diviation
deviation = 64 - counts;
//Depending on the direction
if (incrementer == 1)
value = 64 + deviation;
else
value = 64 - deviation;
MIOS_LCD_Clear();
MIOS_LCD_PrintCString("Encoder #: ");
MIOS_LCD_PrintBCD1(encoder);
if (incrementer == 1)
MIOS_LCD_PrintCString(" Pos");
else if (incrementer == 255)
MIOS_LCD_PrintCString(" Neg");
MIOS_LCD_CursorSet(0x40);
MIOS_LCD_PrintCString("Value: ");
MIOS_LCD_PrintBCD2(value);
MIOS_MIDI_TxBufferPut(0xb0);
MIOS_MIDI_TxBufferPut(encoder);
MIOS_MIDI_TxBufferPut(value);
timer_counter = 0;
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void AIN_NotifyChange(unsigned char pin, unsigned int pin_value)
{
MIOS_LCD_Clear();
MIOS_LCD_CursorSet(0x40);
MIOS_LCD_PrintBCD4(pin);
MIOS_LCD_PrintBCD4(pin_value);
MIOS_LCD_PrintBCD4(MIOS_AIN_Pin7bitGet(pin));
MIOS_MIDI_TxBufferPut(0xb0);
MIOS_MIDI_TxBufferPut(pin);
MIOS_MIDI_TxBufferPut(MIOS_AIN_Pin7bitGet(pin));
}
and in mios_tables.inc:
.
.
.
MIOS_ENC_PIN_TABLE
;; encoders 1-16
;; SR Pin Mode
ENC_ENTRY 1, 2, MIOS_ENC_MODE_DETENTED
ENC_EOT
ENC_EOT
.
.
.
.
Problem:
When I turn encoder very slow, 64 is sent. When I slowly increase the turnspeed the value is supposed to change from 64 to 65-66-67-68-69 and so on to 127.
But….It’s almost impossible to get stable values between 64 and 80 (which is the most important range to fine seek for a beat). Same counter-clockwise, hard to get values between 64 and 40. Value is jumping from 64 to e.i 74.
Am I way off here or have someone else a better solution?
Anyone have some thoughts about this?
/Wise