Switch Cases with analogWrite() funkiness

Hello everybody and thanks for taking a peek here!

I am working on some code for some switch cases, and I am stuck on something that isnt making sense to me at this time.. Ive never used the switch case, but I dont think I should be having this much trouble with it either..

I want to have each switch case output a specific PWM signal to an LED, output a voltage from a digital potentiometer, and read the potentiometer's output voltage from the arduino analog pin A0. It seems to works perfectly fine for all cases 1-10 without any analogWrite functions yet. It also works when case 1 has its analogWrite functions. But as soon as I add an analogWrite() to case 2, it stops displaying feedback on LCD and the LED doesn't light up for case 1 & 2.. The other cases still display LCD feedback though.

This code right here is what it looks like just before I add the analogWrite() to case 2..

while(Serial.available() == 1) {

  // while user input is available, complete this switch statement
  serialInput= Serial.parseInt();
  Serial.end();                 // end serial interface with monitor

  switch (serialInput) {

   case 1:
        analogWrite(4, 230);      // turns on LED to 90% brightness
        SPI.begin();                   // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);    //  chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);         // transfer wiper address
        SPI.transfer(voltageOutput1); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);   // write the chip select pin HIGH to end serial transaction
      SPI.end();

       // print feedback to LCD
      lcd.setCursor(0, 0);     
      lcd.print("voltage feedback" );
      lcd.setCursor(0, 1);
      lcd.print(analogRead(A0));

      delay(LEDduration);

       analogWrite(4, 0);
        SPI.begin();                   // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);     // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);          // transfer wiper address
        SPI.transfer(voltageOutput10); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);    // write the chip select pin HIGH to end serial transaction
      SPI.end();
      
      break;
   
   case 2:
      SPI.begin();                    // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);    // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);         // transfer wiper address
        SPI.transfer(voltageOutput2); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);   // write the chip select pin HIGH to end serial transaction
      SPI.end();      
      
       // print feedback to LCD
      lcd.setCursor(0, 0);     
      lcd.print("voltage feedback" );
      lcd.setCursor(0, 1);
      lcd.print(analogRead(A0) );

      delay(LEDduration);
     
        SPI.begin();                   // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);     // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);          // transfer wiper address
        SPI.transfer(NoVoltageOutput); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);    // write the chip select pin HIGH to end serial transaction

      break;

Has anybody else ever dealt with this issue, and can anyone point out something that Im majorly overlooking?

Attach all the code! There are several ways the code could malfunction.

# include <SPI.h>       // include SPI library for digipot control
# include <LiquidCrystal.h>     // include the LCD library for voltage feedback
LiquidCrystal lcd(2, 3, 10, 11, 12, 13);    // define the pins being used for LCD display


int CS_pin;     // variable for the chip select pin
int wiper1;     // variable for wiper address
int serialInput; // variable for the serial input from monitor
int voltageOutput1; // variable for the value to send to the MCP4151
int voltageOutput2; // variable for the value to send to the MCP4151
int voltageOutput3; // variable for the value to send to the MCP4151
int voltageOutput4; // variable for the value to send to the MCP4151
int voltageOutput5; // variable for the value to send to the MCP4151
int voltageOutput6; // variable for the value to send to the MCP4151
int voltageOutput7; // variable for the value to send to the MCP4151
int voltageOutput8; // variable for the value to send to the MCP4151
int voltageOutput9; // variable for the value to send to the MCP4151
int voltageOutput10; // variable for the value to send to the MCP4151
int NoVoltageOutput;  // variable for the 0 value to send to the MCP4151
int PWMpin;

int fdbkAnalog;
int fdbkVoltage;
int fdbkVoltagePin;

int LEDduration;
int LEDpin;

int LCDfdbkDisplay;

void setup() {
  wiper1 = 0000;
  CS_pin = 53;
  fdbkVoltagePin = A0;
  LEDduration = 2000;

  NoVoltageOutput = 255;
  voltageOutput1 = 230;
  voltageOutput2 = 204;
  voltageOutput3 = 179;
  voltageOutput4 = 153;
  voltageOutput5 = 128;
  voltageOutput6 = 102;
  voltageOutput7 = 77;
  voltageOutput8 = 51;
  voltageOutput9 = 26;
  voltageOutput10 = 0;


  digitalWrite(CS_pin, HIGH);                             // the chip select is written HIGH to make sure no transmissions happen right away
  pinMode(CS_pin, OUTPUT);    // initializes the CS pin as an output pin

}

void loop() {
  lcd.begin(16, 2);           // initializes the LCD screen for feedback display

  SPI.begin();                   // begin serial interface with MCP4151
  digitalWrite(CS_pin, LOW);  // voltageOutput1 brightness for LEDduration;
  SPI.transfer(wiper1);       // transfer wiper address to transfer too
  SPI.transfer(NoVoltageOutput); // transfer write value to set wiper to
  digitalWrite(CS_pin, HIGH);   // write the chip select pin HIGH to end serial transaction
  SPI.end();
  delay(250);     // tiny delay

  Serial.begin(9600);                          // Initializes Serial transactions for use

  while (Serial.available() == 0) {              // do nothing while no input is available

  }

  while (Serial.available() == 1) {
    // while user input is available, complete this switch statement
    serialInput = Serial.parseInt();
    Serial.end();                 // end serial interface with monitor

    switch (serialInput) {

      case 1:
        SPI.begin();                    // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);    // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);         // transfer wiper address
        SPI.transfer(voltageOutput1); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);   // write the chip select pin HIGH to end serial transaction
        SPI.end();

        // print feedback to LCD
        lcd.setCursor(0, 0);
        lcd.print("voltage feedback" );
        lcd.setCursor(0, 1);
        lcd.print(analogRead(A0) );

        analogWrite(4, 230);
        delay(LEDduration);
        analogWrite(4, 0);

        SPI.begin();                   // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);     // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);          // transfer wiper address
        SPI.transfer(NoVoltageOutput); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);    // write the chip select pin HIGH to end serial transaction

        break;

      case 2:
        SPI.begin();                    // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);    // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);         // transfer wiper address
        SPI.transfer(voltageOutput2); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);   // write the chip select pin HIGH to end serial transaction
        SPI.end();

        // print feedback to LCD
        lcd.setCursor(0, 0);
        lcd.print("voltage feedback" );
        lcd.setCursor(0, 1);
        lcd.print(analogRead(A0) );

        delay(LEDduration);

        SPI.begin();                   // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);     // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);          // transfer wiper address
        SPI.transfer(NoVoltageOutput); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);    // write the chip select pin HIGH to end serial transaction

        break;

      default:
        Serial.end();                 // end serial interface with monitor

        // defualt is a blink sequence for LEDduration
        // can post this default case, but I really dont think its affacting what Im troubleshooting
       
        //print error feedback to LCD
        lcd.setCursor(0, 0);
        lcd.print("input error" );
        lcd.setCursor(0, 1);
        lcd.print(analogRead(A0));

    }
    delay(500);
    SPI.end();

  }

}

My first observation is that you do not need to use a massive switch/case for this.

If I understand correctly then depending on a number from 1 to 10 entered by the user then a particular value is written to the pot and the resultant output voltage is read and displayed.

If that is correct then it could be done using an array of 10 values using the user input as the index.

By the way, did you forget about code tags when you posted the complete program ?

UKHeliBob:
My first observation is that you do not need to use a massive switch/case for this.

If I understand correctly then depending on a number from 1 to 10 entered by the user then a particular value is written to the pot and the resultant output voltage is read and displayed.

If that is correct then it could be done using an array of 10 values using the user input as the index.

By the way, did you forget about code tags when you posted the complete program ?

Oh geez.. yeah, I was rushing and forgot to use the code tags.. Sorry, everyone!

And You are probably right about the array. I will try again tomorrow after I read up more about how to use them. It will probably solve my issue, but if anybody has a moment to pick at this, I'd still like to figure out why its only letting me use one analogWrite() for the whole switch/case.. Im very new to writing code for arduino and Im sure Im just overlooking something simple..

Thanks for the suggestion!

Why do you use Serial.begin() and Serial.end() in loop()? Once you use Serial.end(), your while (Serial.available() == 1) will always be false. Serial.begin belongs in setup.

I suspect that the same applies to SPI.begin() and SPI.end(); not familiar with the SPI interface but this comment is based on example code in https://www.arduino.cc/en/Tutorial/DigitalPotControl;

It's a lot easier to initialise your variables when you declare them; this will clean up setup().

// wiper address
const int wiper1 = 0000;

// pins
const byte CS_pin = 53;
const byte fdbkVoltagePin = A0;

// ??
int LEDduration = 2000;

// potentiometer values
int NoVoltageOutput = 255;
int voltageOutput1 = 230;
int voltageOutput2 = 204;
int voltageOutput3 = 179;
int voltageOutput4 = 153;
int voltageOutput5 = 128;
int voltageOutput6 = 102;
int voltageOutput7 = 77;
int voltageOutput8 = 51;
int voltageOutput9 = 26;
int voltageOutput10 = 0;

void setup()
{
  Serial.begin(9600);

  digitalWrite(CS_pin, HIGH); // the chip select is written HIGH to make sure no transmissions happen right away
  pinMode(CS_pin, OUTPUT);    // initializes the CS pin as an output pin

  SPI.begin();
}

void loop()
{
  ...
  ...

  // no need for Serial.begin/Serial.end
  // no need for SPI.begin/end 
}

Notes:
1)
you never gave ledPin a value so it defaults to 0; you did not use it anywhere so that's OK for now
2)
all your potentiometer values fit in a byte; depending on the spec of the potentiometer, you might be able to change int to byte
3)
all variables that don't change can be made const as I demonstrated for the pins and the address

sterretje:
Why do you use Serial.begin() and Serial.end() in loop()? Once you use Serial.end(), your while (Serial.available() == 1) will always be false. Serial.begin belongs in setup.

I suspect that the same applies to SPI.begin() and SPI.end(); not familiar with the SPI interface but this comment is based on example code in https://www.arduino.cc/en/Tutorial/DigitalPotControl;

It's a lot easier to initialise your variables when you declare them; this will clean up setup().

// wiper address

const int wiper1 = 0000;

// pins
const byte CS_pin = 53;
const byte fdbkVoltagePin = A0;

// ??
int LEDduration = 2000;

// potentiometer values
int NoVoltageOutput = 255;
int voltageOutput1 = 230;
int voltageOutput2 = 204;
int voltageOutput3 = 179;
int voltageOutput4 = 153;
int voltageOutput5 = 128;
int voltageOutput6 = 102;
int voltageOutput7 = 77;
int voltageOutput8 = 51;
int voltageOutput9 = 26;
int voltageOutput10 = 0;

void setup()
{
 Serial.begin(9600);

digitalWrite(CS_pin, HIGH); // the chip select is written HIGH to make sure no transmissions happen right away
 pinMode(CS_pin, OUTPUT);    // initializes the CS pin as an output pin

SPI.begin();
}

void loop()
{
 ...
 ...

// no need for Serial.begin/Serial.end
 // no need for SPI.begin/end
}



Notes:
1)
you never gave ledPin a value so it defaults to 0; you did not use it anywhere so that's OK for now
2)
all your potentiometer values fit in a byte; depending on the spec of the potentiometer, you might be able to change int to byte
3)
all variables that don't change can be made *const* as I demonstrated for the pins and the address

Thanks for giving me those tips! I will most definitely make the suggested changes to my code and try to remember those for the future.

The reason I end and start the SPI and the serial transactions is because I was thinking that since I was using serial interfacing with two devices, I could only communicate with one device at a time. I know that multiple slave devices can be hooked up to one master as long as you enable only one at a time, so that was my logic. BUT I have ALOT to learn.. any information or pointers that I could use are much appreciated.

-as for the LEDpin variable, I meant to use that for the analogWrite().
-I will change my potentiometer values to byte, thanks for the helpful reminder!
-all non changing variables will be switched to const variables.

I took all suggestions into consideration, and tested out a few things and this is what works now! Thanks to anybody who took the time to point out my rookie mistakes and give me pointers!

I changed some variables to const variable to start. I tried it without all of the extra SPI.begin/end and the Serial.begin/end, but it didnt seem to work, so I put them back in where I had them…

here is the code though so yall can see how its working. I omitted cases 3-10(they are all the same aside from output variables).

# include <SPI.h>       // include SPI library for digipot control
# include <LiquidCrystal.h>     // include the LCD library for voltage feedback
LiquidCrystal lcd(2, 3, 10, 11, 12, 13);    // define the pins being used for LCD display


const int CS_pin = 53;     // variable for the chip select pin
const int wiper1 = 0000;     // variable for wiper address
int serialInput; // variable for the serial input from monitor
const int NoVoltageOutput = 0;  // variable for the 0 value to send to the MCP4151
const int voltageOutput1 = 26; // variable for the value to send to the MCP4151
const int voltageOutput2 = 51; // variable for the value to send to the MCP4151
const int voltageOutput3 = 77; // variable for the value to send to the MCP4151
const int voltageOutput4 = 102; // variable for the value to send to the MCP4151
const int voltageOutput5 = 128; // variable for the value to send to the MCP4151
const int voltageOutput6 = 153; // variable for the value to send to the MCP4151
const int voltageOutput7 = 179; // variable for the value to send to the MCP4151
const int voltageOutput8 = 204; // variable for the value to send to the MCP4151
const int voltageOutput9 = 230; // variable for the value to send to the MCP4151
const int voltageOutput10 = 255; // variable for the value to send to the MCP4151

int fdbkAnalog;
int fdbkVoltage;
int fdbkVoltagePin = A0;

int LEDduration = 2000;
const int LEDpin = 4;

int LCDfdbkDisplay;

void setup() {
  digitalWrite(CS_pin, HIGH);                             // the chip select is written HIGH to make sure no transmissions happen right away
  pinMode(CS_pin, OUTPUT);    // initializes the CS pin as an output pin

}

void loop() {
  lcd.begin(16, 2);           // initializes the LCD screen for feedback display
  Serial.begin(9600);                          // Initializes Serial transactions for use
  SPI.begin();                   // begin serial interface with MCP4151

  digitalWrite(CS_pin, LOW);  // voltageOutput1 brightness for LEDduration;
  SPI.transfer(wiper1);       // transfer wiper address to transfer too
  SPI.transfer(NoVoltageOutput); // transfer write value to set wiper to
  digitalWrite(CS_pin, HIGH);   // write the chip select pin HIGH to end serial transaction
  SPI.end();
  delay(250);     // tiny delay


  while (Serial.available() == 0) {              // do nothing while no input is available

  }

  while (Serial.available() == 1) {
    serialInput = Serial.parseInt();
    Serial.end();                 // end serial interface with monitor

    switch (serialInput) {

      case 1:
        SPI.begin();                    // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);    // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);         // transfer wiper address
        SPI.transfer(voltageOutput1); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);   // write the chip select pin HIGH to end serial transaction
        SPI.end();

        // print feedback to LCD
        lcd.setCursor(0, 0);
        lcd.print("voltage feedback" );
        lcd.setCursor(0, 1);
        lcd.print(analogRead(fdbkVoltagePin) );

        analogWrite(LEDpin, 26);
        delay(LEDduration);
        analogWrite(LEDpin, 0);

        SPI.begin();                   // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);     // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);          // transfer wiper address
        SPI.transfer(NoVoltageOutput); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);    // write the chip select pin HIGH to end serial transaction

        break;

      case 2:
        SPI.begin();                    // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);    // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);         // transfer wiper address
        SPI.transfer(voltageOutput2); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);   // write the chip select pin HIGH to end serial transaction
        SPI.end();

        // print feedback to LCD
        lcd.setCursor(0, 0);
        lcd.print("voltage feedback" );
        lcd.setCursor(0, 1);
        lcd.print(analogRead(fdbkVoltagePin) );

        analogWrite(LEDpin, 51);
        delay(LEDduration);
        analogWrite(LEDpin, 0);

        SPI.begin();                   // begin serial interface with MCP4151
        digitalWrite(CS_pin, LOW);     // chip select pin is written LOW to enable data transfer;
        SPI.transfer(wiper1);          // transfer wiper address
        SPI.transfer(NoVoltageOutput); // transfer write value to set wiper to
        digitalWrite(CS_pin, HIGH);    // write the chip select pin HIGH to end serial transaction

        break;

      default:
        Serial.end();                 // end serial interface with monitor
        // defualt is a blink sequence for LEDduration

        //print error feedback to LCD
        lcd.setCursor(0, 0);
        lcd.print("input error" );
        lcd.setCursor(0, 1);
        lcd.print(analogRead(fdbkVoltagePin));

      analogWrite(LEDpin, 255);
      delay(500);
      analogWrite(LEDpin, 0);
      delay(500);
      analogWrite(LEDpin, 255);
      delay(500);
      analogWrite(LEDpin, 0);
      delay(500);
      analogWrite(LEDpin, 255);
      delay(500);
      analogWrite(LEDpin, 0);
      delay(500);    
      

    
    SPI.end();

  }

}
}

Serial is not the same as Serial Peripheral Interface. They will not interfere.

I forgot to mention that lcd.begin also should not be placed in loop(). If I'm not mistaken, it will clear the lcd each time.

Put one Serial.begin(9600) and one SPI.begin() in Setup! And drop the .end.

Show the code that was based on my suggestion and showed the same behaviour that you descrived in the opening post.