Welcome, Guest
Username: Password: Remember me

TOPIC: Coding multiple effects controlled by rotary sw

Coding multiple effects controlled by rotary sw 6 months 2 weeks ago #695

  • Kosak
  • Kosak's Avatar
  • OFFLINE
  • New Member
  • Posts: 4
  • Karma: 0
Hi! Really great idea behind the pedal! :)
I would like to ask about the way to put 3 effects in one program and control them with the 3 position rotary switch.
Switch has 4 PINs - one GND and 3 others.

1. I have connected (could be that incorrectly), GND to GND (obviously :D) and 3 other to analog PINs on Arduino: A5, A4 and A3.
2. In program I have defined them, made them pinMode(PIN, INPUT_PULLUP).
3. Then in the ISR() section, I have tried something like:
if(!digitalRead(PIN1))
{ all effect1 code here;
}
if(!digitalRead(PIN2))
{ all effect2 code here;
}
and so on, but even if it worked for one change of state, it wouldn't go back, and would switch off my LCD completely. Is there any correct way to do it?

btw - what's the difference between digitalRead and !digitalRead? :D
Last Edit: 6 months 2 weeks ago by Kosak. Reason: typos
The administrator has disabled public write access.

Coding multiple effects controlled by rotary sw 6 months 2 weeks ago #696

  • Ray
  • Ray's Avatar
  • NOW ONLINE
  • Administrator
  • Posts: 322
  • Thank you received: 66
  • Karma: 12
Hi,
I have never worked with rotary switches but in the Arduino forums there is a lot of documentation, so I am sure you can get plenty of ideas from there.
The code youve posted can be translated as:
if(digitalRead(PIN1)==0)
{ all effect1 code here;
}
if(digitalRead(PIN2)==0)
{ all effect2 code here;
}
! means "not"

To do your code I would suggest to start simple, maybe a code that blinks an LED at 3 different speeds is a good idea. Once you have it working you can change the part of blinking the LED for different guitar pedals so you build something from easy to complex.

Your code looks good, maybe you can upload your whole code so I can try to help...
The administrator has disabled public write access.

Coding multiple effects controlled by rotary sw 6 months 2 weeks ago #697

  • Kosak
  • Kosak's Avatar
  • OFFLINE
  • New Member
  • Posts: 4
  • Karma: 0
Code is actually quite big already, and the thing is - not sure how having the 2 effects (or more) in one program should look like. In theory should be something like this below, but not sure how to code it correctly. Basically - Doesn't matter if it is controlled by rotary switch, push-button, or anything, just not sure how to put 2 effects together :)
in the begging all defined as in the default effects posted on forum
All PWM and ADC correct (tested with one effect at once)
all variables set up
However, when it comes to timer bit, not sure how to put it here, as this below doesn't work right, or to say - at all.
ISR(TIMER1_CAPT_vect) {
if(digitalRead(PIN1)==HIGH) //when the HIGH state is detected on PIN1
{ //distortion
  // get ADC data
  ADC_low = ADCL; // you need to fetch the low byte first
  ADC_high = ADCH;
  //construct the input sumple summing the ADC low and high byte.
  input = ((ADC_high << 8) | ADC_low) + 0x8000; // make a signed 16b value
 
  //the input signal is 16bits (values from -32768 to +32768
  //the valueif(input>distortion_threshold) input=distortion_threshold; is clipped to the distortion_threshold value
    if(input>distortion_threshold) input=distortion_threshold;
 
  //write the PWM signal
  OCR1AL = ((input + 0x8000) >> 8); // convert to unsigned, send out high byte
  OCR1BL = input; // send out low byte
}
//------------------------------------------------------------------------------------------------------------------------
if(digitalRead(PIN2)==HIGH) //when the HIGH state is detected on PIN2
{//daft-punk
counter2++;
if(counter2>=dist_variable)
{ 
counter2=0;
 
  // get ADC data
  ADC_low = ADCL; // you need to fetch the low byte first
  ADC_high = ADCH;
  //construct the input sumple summing the ADC low and high byte.
  input = ((ADC_high << 8) | ADC_low) + 0x8000; // make a signed 16b value
 
  OCR1AL = ((input + 0x8000) >> 8); // convert to unsigned, send out high byte
  OCR1BL = input; // send out low byte
}
}
}
Last Edit: 6 months 2 weeks ago by Kosak.
The administrator has disabled public write access.

Coding multiple effects controlled by rotary sw 6 months 2 weeks ago #700

  • Ray
  • Ray's Avatar
  • NOW ONLINE
  • Administrator
  • Posts: 322
  • Thank you received: 66
  • Karma: 12
Hi,
The first thing that makes me think is
if(digitalRead(PIN1)==HIGH)
As far as I know you are using internall pullups and when the pin is selected, is grounded. So shouldnt be something like:
if(digitalRead(PIN1)==LOW)

I am assuming that the digital pins are correctly wired too.

I would use If/else construction, I takes less resources. You are doing if/if/if.. that makes the microcontroller to check all the possible variations even if the first "if" is the one selected.

I would start with something like this:
ISR(TIMER1_CAPT_vect)
 {
if(digitalRead(PIN1)==HIGH) //when the HIGH state is detected on PIN1
{digitalWrite(LED, LOW);}
 
else if(digitalRead(PIN2)==HIGH) //when the HIGH state is detected on PIN2
{digitalWrite(LED, HIGH);}
}

It is very simple, and once you get it working you can add more stuff.
The administrator has disabled public write access.

Coding multiple effects controlled by rotary sw 6 months 1 week ago #706

  • Kosak
  • Kosak's Avatar
  • OFFLINE
  • New Member
  • Posts: 4
  • Karma: 0
Ok, see. I got it somehow working, but seems like this timer1 interruption interferes with the millis() function? As my timer gets corrupted once effect is used. Do you have any experience with that? Or maybe - is it possible to put the effect interrupt to timer0 or 2? If yes, how it can be done?
The administrator has disabled public write access.

Coding multiple effects controlled by rotary sw 6 months 1 week ago #710

  • Ray
  • Ray's Avatar
  • NOW ONLINE
  • Administrator
  • Posts: 322
  • Thank you received: 66
  • Karma: 12
yes, I think I remember reading on the arduino forums that timer 1 mess with the millis functions.
In theory you can change the interruption to timer 0 or 2 but I never try to to that, I think that may be easier to try to make a work around and not use the millis.
The administrator has disabled public write access.

Coding multiple effects controlled by rotary sw 1 month 1 week ago #909

  • Beniamino
  • Beniamino's Avatar
  • OFFLINE
  • New Member
  • Posts: 4
  • Karma: 0
I tried to use the switch to control programs. This is the program i wrote but it doesn't work well: the switch donesn't change the effects. Is there something wrong?

//defining hardware resources.
#define LED 13
#define FOOTSWITCH 12
#define TOGGLE 2
#define PUSHBUTTON_1 A5
#define PUSHBUTTON_2 A4

//defining the output PWM parameters
#define PWM_FREQ 0x00FF // pwm frequency - 31.3KHz
#define PWM_MODE 0 // Fast (1) or Phase Correct (0)
#define PWM_QTY 2 // 2 PWMs in parallel

//other variables
int input, distortion_threshold=6000, vol_variable=512; //initial value adjusted by try and error.
int counter=0;
unsigned int ADC_low, ADC_high;

void setup() {
//setup IO
pinMode(FOOTSWITCH, INPUT_PULLUP);
pinMode(PUSHBUTTON_1, INPUT_PULLUP);
pinMode(PUSHBUTTON_2, INPUT_PULLUP);
pinMode(LED, OUTPUT);
pinMode(TOGGLE, INPUT);
// setup ADC
ADMUX = 0x60; // left adjust, adc0, internal vcc
ADCSRA = 0xe5; // turn on adc, ck/32, auto trigger
ADCSRB = 0x07; // t1 capture for trigger
DIDR0 = 0x01; // turn off digital inputs for adc0

// setup PWM
TCCR1A = (((PWM_QTY - 1) << 5) | 0x80 | (PWM_MODE << 1)); //
TCCR1B = ((PWM_MODE << 3) | 0x11); // ck/1
TIMSK1 = 0x20; // interrupt on capture interrupt
ICR1H = (PWM_FREQ >> 8);
ICR1L = (PWM_FREQ & 0xff);
DDRB |= ((PWM_QTY << 1) | 0x02); // turn on outputs
sei(); // turn on interrupts - not really necessary with arduino
}

void loop() {
//Turn on the LED if the effect is ON.
if (digitalRead(FOOTSWITCH)==HIGH) digitalWrite(LED, HIGH);
else digitalWrite(LED, LOW);

//nothing else here, all happens in the Timer 1 interruption.
}

ISR(TIMER1_CAPT_vect)
{
// get ADC data
ADC_low = ADCL; // you need to fetch the low byte first
ADC_high = ADCH;
//construct the input sumple summing the ADC low and high byte.
input = ((ADC_high << 8) | ADC_low) + 0x8000; // make a signed 16b value

if(digitalRead(TOGGLE)==HIGH)
{
counter++; //to save resources, the pushbuttons are checked every 1000 times.
if(counter==1000)
{
counter=0;
if (!digitalRead(PUSHBUTTON_2)) {
if (distortion_threshold<32768)distortion_threshold=distortion_threshold+25; //increase the vol
digitalWrite(LED, LOW); //blinks the led
}

if (!digitalRead(PUSHBUTTON_1)) {
if (distortion_threshold>0)distortion_threshold=distortion_threshold-25; //decrease vol
digitalWrite(LED, LOW); //blinks the led
}
}

//the input signal is 16bits (values from -32768 to +32768
//the value of input is clipped to the distortion_threshold value
if(input>distortion_threshold) input=distortion_threshold;

//write the PWM signal
OCR1AL = ((input + 0x8000) >> 8); // convert to unsigned, send out high byte
OCR1BL = input; // send out low byte
}
else
{
//write the PWM signal
OCR1AL = ((input + 0x8000) >> 8); // convert to unsigned, send out high byte
OCR1BL = input; // send out low byte
}
}
Last Edit: 1 month 1 week ago by Beniamino.
The administrator has disabled public write access.

Coding multiple effects controlled by rotary sw 1 month 1 week ago #910

  • Ray
  • Ray's Avatar
  • NOW ONLINE
  • Administrator
  • Posts: 322
  • Thank you received: 66
  • Karma: 12
Hi Beniamino, could you post the wiring you are using? it is not clear for me how your rotary switch is connected to the hardware.
The administrator has disabled public write access.
Time to create page: 0.995 seconds
Powered by Kunena Forum
Joomla SEF URLs by Artio