SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
By Mfive
#192976
I am using an Arduino pro, zx gesture sensor and the SI4703 evalution FM Radio board for this project. My intention is to change radio channels with each swipe (left or right). The variable x in my code determines the radio channel. However, when I swipe my hand right the first time, the variable x jumps from 0 to 3! (bypassing 1 and 2) I was wondering why this is so. It appears that there may be a loop that causes x++ to repeat until x=3? But then again, shouldn’t the ‘break’; in the code prevent the switch statement from repeating? It would be great if someone could help me by pointing out where my error is and how I can correct it.

My code is shown below:
Code: Select all
#include <SoftwareSerial.h>
#include <Wire.h>
#include <ZX_Sensor.h>
#include <Si4703_Breakout.h>

// Global Variables
SoftwareSerial soft_serial(10, 11);  // RX, TX
uint8_t c;

int resetPin = 2;
int SDIO = A4;
int SCLK = A5;

Si4703_Breakout radio(resetPin, SDIO, SCLK);
int channel;
int volume;
char rdsBuffer[10];

int x = 0;

void setup() {
  
  // Initialize hardware serial port. Note the baud rate.
  Serial.begin(115200);
  Serial.println();
  Serial.println("-----------------------------------------");
  Serial.println("SparkFun/GestureSense - UART Gesture Demo");
  Serial.println("Note: higher 'speed' numbers mean slower");
  Serial.println("-----------------------------------------");
  
  // Initialize software serial port
  soft_serial.begin(115200);
  radio.powerOn();
  radio.setVolume(0);
}

void loop() {
  
  // Read in a character from the UART
  if ( soft_serial.available() ) {
    c = soft_serial.read();
    
    // Determine type of message and print it
    switch ( c ) {
      case ZX_UART_GESTURE:
      
        // Determine type of gesture
        c = soft_serial.read();
        switch ( c ) {
          case RIGHT_SWIPE:
            c = soft_serial.read();
            Serial.print("Right Swipe");
            //Serial.println(c, DEC);
            Serial.print(x);
            myswiperightfunction();
            break;
          case LEFT_SWIPE:
            c = soft_serial.read();
            Serial.print("Left Swipe");
            //Serial.println(c, DEC);
            Serial.print(x);
            myswipeleftfunction();
            break;
          case UP_SWIPE:
            c = soft_serial.read();
            Serial.print("Up Swipe");
            Serial.println(c, DEC);
            volume ++;
            if (volume == 16) volume = 15;
            radio.setVolume(volume);
          default:
            break;
        case ZX_UART_Z:
        Serial.print("Z: ");
        c = soft_serial.read();
        Serial.println(c, DEC);
        }
        
        break;
    }
  }
}

void myswiperightfunction(){
  radio.setVolume(1);
  x++;
  if (x = 1) {
  channel = 915; // Station 1
  radio.setChannel(channel);
  }
  
  if (x = 2) {
  channel = 1003; // Station 2
  radio.setChannel(channel);
  }
  
  if (x = 3) {
  channel = 1019; // Station 3
  radio.setChannel(channel);

  
  }
}

void myswipeleftfunction(){
  radio.setVolume(1);
  x--;
    if (x = 1) {
  channel = 915; // Station 1
  radio.setChannel(channel);
  }
  
  if (x = 2) {
  channel = 1003; // Station 2
  radio.setChannel(channel);
  }
  
  if (x = 3) {
  channel = 1019; // Station 3
  radio.setChannel(channel);
  }
}

By Valen
#192988
In your code you only partially send the state of your code to the hardware serial port when something is received from the gesture sensor. Then you could miss out on essential data indicating multiple gestures detected. Don't just send the x values. Which are internal values of the channel state only. If something strange is received, then gesture parameters could be interpreted a commands an your program could get out of sync with the sensor. Send whenever you read something from the software serial port also to the hardware serial port to make sure you know what it is getting.

You are missing the if-statements that put x back between 1 and 3 if it somehow gets outside of that range. You DO do range checks in the UP_SWIPE switch case though. Why not when changing channels?
By Mfive
#192995
Thanks for the advice Valen. I initially did not include the range checks as I wanted to focus on the problem of the variable that is jumping across values, however, as advised, I have now included range check in my code for both swipes.

I wanted to clarify more about what you meant by not just sending the x values, but to send whenever I read something from the software and hardware serial port. How should I implement this modification in my code?
By Valen
#193004
On second look at the code you already have most of those serial.println functions in your code but some there are commented out. I would leave then enabled until it all works as it should. But right at the top (before comment // Determine type of message and print it), just before entering the second switch statement I would send the content of variable c also. (with another serial.println descriptive text telling you that it determined there is a gesture message coming in)

Since you print X right before myswiperightfunction or myswipeleftfunction it is possible to figure out to which channel it will change. Except the increment and decrement of x after the printing of x makes this a bit confusing. After the channel was set I would also print to serial the actual channel number to which it is set, to avoid confusion.

With this you should get all the message identifier (ZX_UART_GESTURE) and parameter values in view in the serial monitor. And you should be able to match that with how you are swiping on the gesture sensor. Compare the numbers printed to serial monitor with how the gesture messages protocol is structured and what gestures you make.

I noticed you have 2 switch statements, one wrapped inside the other. Both of them switch based on the variable c which you set with a serial.read in the second one. That could get your program execution messed up. It might be prudent to name one of them differently. Or it seems as if the last switch case ZX_UART_Z (which to me ought to belong to the outer one) is placed inside the curly-bracket of the inner switch-statement. It is evaluated after the default case of the inner one. Select one of the curly-brackets in the Arduino IDE and see which complementary bracket is highlighted. That is probably not as it should be. But I am unfamiliar with the gesture message protocol. It may be correct after all.