Help with serials and strings

edited July 2015 in Arduino

Hi Processing Forum,

I am in the process of hacking a rotary phone, using Arduino and Processing to convert the phone into a recording and playback device. It is a really interesting project and I have made some progress, but I got stuck on a string from the serial port. My code is long, so I will share my public gist here: https://gist.github.com/lizzybrooks/b88531b906860d4fc4af.

Here is the function that seems to be giving me trouble:

void readNumbers(){
if ( myPort.available() > 0) 
  {  
    // get the value from the serial port
    do{
    val = myPort.readStringUntil('\n');         // read it and store it in val 
    } while (val == null);

    // print every value received to the console so we know what we got
   // println(val);
   // println(val.length()); 

if (val.equals("6\r\n")){
      println("hooray. you work. let's play a different audio file");

      // anything else and its input from the phone
      // so do whatever you want if you receive input from the phone here...
    }

  }

If you have any ideas or can help me with syntax, I would so much appreciate it. I am a beginner coder working on a complicated project, but I am eager to learn.

Thanks so much!

Lizzy

Answers

  • maybe

    val=trim(val);

  • edited July 2015

    Hmm.. that didn't seem to make a difference. Maybe I am not adding it in the correct way? Here's the code now. It works up until the readNumbers function, which does not work.

        import processing.serial.*;
        import ddf.minim.*;
    
        Minim minim;
        AudioPlayer player;
        AudioInput input;
    
    
        Serial myPort;  // Create object from Serial class
        String val;     // Data received from the serial port 
    
        void setup() {
          minim = new Minim(this);
          player = minim.loadFile("makeroom.mp3");
          input = minim.getLineIn(); 
    
            String portName = Serial.list()[2]; //change the 0 to a 1 or 2 etc. to match your port
          myPort = new Serial(this, portName, 9600); 
    
        }
    
        void draw()
        {
          checkArduino();
          resetProgram();
          dialTone();
          readNumbers();
    
        }
    
        void checkArduino()
        {
            // If data is available, 
          if ( myPort.available() > 0) 
          {  
            // get the value from the serial port
            do{
            val = myPort.readStringUntil('\n');         // read it and store it in val STAY HERE until you find something
            } while (val == null);
    
            // print every value received to the console so we know what we got
            //println(val);
            //println(val.length());
    
    
          }
        }
    
        void resetProgram(){
          // read a byte from the serial port:
          int inByte = myPort.read();
            if (inByte == 'A') { 
              println("reset program");
               myPort.write('B');
            } 
          } 
    
        void dialTone(){
          if (val.equals("dial tone\r\n")){
              // do whatever you want to do when you receive a dial tone
               player.play();
               println("Play");
    
            } 
           else if (val.equals("number\r\n")){
              player.pause();
              println("Stop");
              super.stop();
            }
        }
    
    
        void readNumbers(){
          val=trim(val);
    
        if ( myPort.available() > 0) 
          {  
            // get the value from the serial port
            do{
            val = myPort.readStringUntil('\n');         // read it and store it in val STAY HERE until you find something
            } while (val == null);
    
            // print every value received to the console so we know what we got
           // println(val);
           // println(val.length()); 
    
        if (val.equals("6")){
              println("hooray. you work. let's play a different audio file");
    
              // anything else and its input from the phone
              // so do whatever you want if you receive input from the phone here...
            }
    
          }
    
        }
    
  • The   val=trim(val); line belongs at line 82, after there's a val to work with.

  • edited July 2015

    You don't actually say what the trouble is.

    What do you expect to happen?
    and
    What actually happens?

  • edited July 2015

    Hi, thanks for checking this out. I am trying to control a rotary phone with Processing, via Arduino. What I expect to happen is that the processing program reads the string val from the Arduino via the serial port.

    If val is "dial tone", then the program plays an audio file. If the rotary dial is moving, the audio file pauses. If the phone's receiver is placed on the hook, the audio file pauses, and the program resets, enabling another dial tone. If val is "6", then the program prints "hooray. you work." Eventually I want to play a different audio file with the dialed number 6.

    Everything works except val.equals("6"). I am able to send "6" from Arduino to Processing if I take away the rest of the code, but when I combine it with the other functions, "6" does not come through.

    I am including code for both Arduino and Processing here. Thanks very much for taking a look!

    Processing Code:

        import processing.serial.*;
        import ddf.minim.*;
    
        Minim minim;
        AudioPlayer player;
        AudioInput input;
    
    
        Serial myPort;  // Create object from Serial class
        String val;     // Data received from the serial port 
    
        void setup() {
          minim = new Minim(this);
          player = minim.loadFile("makeroom.mp3");
          input = minim.getLineIn(); 
    
            String portName = Serial.list()[2]; //change the 0 to a 1 or 2 etc. to match your port
          myPort = new Serial(this, portName, 9600); 
    
        }
    
        void draw()
        {
    
        background(0);
        println(val); 
        readSerial();
        reset();  
        playTone();
        dial();
    
    
    
        }
    
        void readSerial(){
           if ( myPort.available() > 0) 
          {  
            // get the value from the serial port
            do{
            val = myPort.readStringUntil('\n');         // read it and store it in val STAY HERE until you find something
            } while (val == null);
    
            // print every value received to the console so we know what we got
            //println(val);
    
          }
        }
    
        void reset(){
          // read a byte from the serial port:
          int inByte = myPort.read();
            if (inByte == 'A') { 
               player.pause();
           // super.stop();
             println("reset program");
               myPort.write('B');
            } 
          } 
    
        void playTone(){  
          do{
            val = myPort.readStringUntil('\n');         // read it and store it in val STAY HERE until you find something
            } while (val == null);
          val=trim(val);
           if (val.equals("ial tone")){
              // do whatever you want to do when you receive a dial tone
               player.play();
               println("Play");
    
            } 
        }
    
        void dial(){
           do{
            val = myPort.readStringUntil('\n');         // read it and store it in val STAY HERE until you find something
            } while (val == null);
          val=trim(val);
    
           if (val.equals("dialing")){
               player.pause(); //stop the dial tone
               myPort.write('C'); // keep the dial tone from immediately restarting by sending a serial to arduino
              println("dial number");
    
            } 
    
           if (val.equals("6")){
              println("hooray. you work. let's play a different audio file");
              //player.play();
    
              // anything else and its input from the phone
              // so do whatever you want if you receive input from the phone here...
            }
            else {
             // println("wrong number");
        }
    
        }
    

    Arduino Code:

            /* Basic Digital Read
             * ------------------ 
             * This code reads whether the phone is on the hook by treating that hook like a button that is either open or depressed
             */
    
            #define INITPIN 12
            #define NUMPIN 11
    
            int counter; // holds the pulse count for each dial spin
            int currentValue = 0; 
            long lastDebounceTime = 0;  // the last time the output pin was toggled
            long debounceDelay = 5;    // the debounce time; increase if the output flickers
    
            int ledPin = 13; // choose the pin for the LED
            int inPin = 7;   // choose the input pin (for a pushbutton)
            int val = 0;     // variable for reading the pin status
            int incomingByte = 0; //for incoming serial data
    
            void setup(){
               Serial.begin(9600);
    
            //configure the rotary wheel pins   
                pinMode(INITPIN, INPUT_PULLUP); 
                pinMode(NUMPIN, INPUT_PULLUP);
    
            // configure the hook inputs, and the onboard LED.
              pinMode(ledPin, OUTPUT);  // declare LED as output
              pinMode(inPin, INPUT);    // declare phone hook as input
            }
    
            void loop(){
    
            hookReader();
            dialNumber();
    
            }
    
            void hookReader(){  
              // send data only when you receive data:
                    if (Serial.available() > 0) {
                            // read the incoming byte:
                            incomingByte = Serial.read();
    
                            // say what you got:
                            Serial.print("I received: ");
                            Serial.println(incomingByte, DEC);
                    }
    
    
    
                int initRead = digitalRead (INITPIN); // Is the wheel turning or not?
              static int lastValue = HIGH;  // holds the last read from the pulse pin.   
    
               val = digitalRead(inPin);  // read input value
    
              if (val == LOW && incomingByte == 'B' && incomingByte != 'C') {        
               digitalWrite(ledPin, LOW);  // turn LED OFF
                Serial.println("dial tone");
                 delay(1);        // delay in between reads for stability
    
    
              } else if (val == HIGH) {
                 // check if the input is HIGH (button released)
                digitalWrite(ledPin, HIGH);  // turn LED ON
                Serial.println("on the hook");   // print "on the hook"
                Serial.print('A');
                delay(1);        // delay in between reads for stability
              }
    
    
    
              if (initRead == LOW) {  // If the wheel is turning....
              Serial.println("dialing");
             }   
    
              else {
                Serial.println("waiting");
              }    
    
            }
    
            void dialNumber(){
    
                int initRead = digitalRead (INITPIN); // Is the wheel turning or not?
              static int lastValue = HIGH;  // holds the last read from the pulse pin.
    
              if (initRead == LOW) {  // If the wheel is turning....
                int newValue = digitalRead (NUMPIN); // check the pulse pin.
                if (newValue != lastValue) { // if it's CHANGED from the last read...
                  lastDebounceTime = millis(); // save its clock cycle; we need to check it.
                }
                // If enough time has passed (aka, it's not just a "bounce" from the 
                // analog signal)...
                if ((millis() - lastDebounceTime) > debounceDelay) { 
                  // and if the current value is DIFFERENT than the one you just read...
                  if (currentValue != newValue) { 
                    currentValue = newValue; // make them the same.
                    if (newValue == 1) { // If you just set it to a 1...
                      counter++; // it just finished a pulse, so add one to the counter.
                    }
                  }
                }
    
                lastValue = newValue; // Your new value becomes the old one for comparison.
    
              } else {
            // once the dial returns home and switches the initializing pin OFF,
            // you can be sure that there will be no more pulses coming.
            // "Counter" is the number dialed. You may now use it for whatever you want.
            // This is adjusted for the special case of "0" actually being 10 pulses.
                if (counter > 0) {
                  if (counter == 10) {
                    Serial.println (0);
                  } else {
                    Serial.println (counter);
                  }
                }
            // After you're done using it, reset counter so it can start again on the
            // next dial.
                counter = 0;
              }  
            }
    

    `

  • edited July 2015

    Hi dear thanks a lot of way. I am very happy know about Arduino you understood step by step. I knew already from robomart.com

  • In draw() you have

    readSerial();
    reset();  
    playTone();
    dial();
    

    Assume that readSerial reads the String "6" and assume reset method does nothing. Now playTone() reads another string from the Serial port overriding the value "6" so by the time we get to dial() you read yet another string the chances are it isn't "6"

    Only use readSerial to read the port into a variable. The other methods just act on the value of the variable and do not read the port.

  • The below code uses Arduino and Processing to turn a rotary phone into an audio recorder and playback machine. The Arduino program runs a loop, depending on inputs from the phone, and it sends strings to Processing to record and play audio files using the Minim player.

    The code below is working to do the following: 1) play an operator's voice when the phone comes off the hook 2) record and play one track using the phone's receiver as a headset 3) stop recording or playing when the phone is hung up

    Thanks for your help in previous threads. I just wanted to post the working code here in case anyone uses this.

    Arduino code

    /* Basic Digital Read and Rotary Phone Dial Reader
     * ------------------ 
     * This code reads whether the phone is on the hook by treating that hook like a button that is either open or depressed
    AND it reads out the number dialed on a rotary phone dial by counting the pulses made by the spinning dial wheel. 
    
    
     */
    
    
    #define INITPIN 12
    #define NUMPIN 11
    
    int counter; // holds the pulse count for each dial spin
    int currentValue = 0; 
    long lastDebounceTime = 0;  // the last time the output pin was toggled
    long debounceDelay = 5;    // the debounce time; increase if the output flickers
    
    int inPin = 7;   // choose the input pin (for a pushbutton)
    int val = 0;     // variable for reading the pin status
    
    
    
    void setup(){
       Serial.begin(9600);
    
      //configure the dial reading inputs 
      pinMode(INITPIN, INPUT_PULLUP);
      pinMode(NUMPIN, INPUT_PULLUP);
    
    
     pinMode(inPin, INPUT);    // declare phone hook as input
    }
    
    void loop(){  
    
    
        do { stopOperator(); } //when the phone is on the hook, don't play the operator's voice (or the dial tone)
          while (digitalRead(inPin) == HIGH ); // wait for phone to be picked up for the first time
          delay(100); // wait 100 milliseconds
       Serial.println("play operator"); // tell processing to turn on operator voice
    
       do { if (digitalRead (INITPIN) == LOW) { //if the wheel starts turning
                     stopOperator();  //stop the operator voice
                     readNumber(); //read and react to the numbers
                     }
    
       } while (digitalRead(inPin) == LOW); //while the phone is off the hook
     delay(100); //   chill for a sec
    
    
    }
    
    void stopOperator(){
      Serial.println("stop operator"); 
    }
    
    void endRecording(){
      Serial.println("stop recording");
    }
    
    
    void readNumber(){
      int initRead = digitalRead (INITPIN); // Is the wheel turning or not?
      static int lastValue = HIGH;  // holds the last read from the pulse pin.
    
      if (initRead == LOW) {  // If the wheel is turning....
    
        int newValue = digitalRead (NUMPIN); // check the pulse pin.
        if (newValue != lastValue) { // if it's CHANGED from the last read...
          lastDebounceTime = millis(); // save its clock cycle; we need to check it.
        }
        // If enough time has passed (aka, it's not just a "bounce" from the 
        // analog signal)...
        if ((millis() - lastDebounceTime) > debounceDelay) { 
          // and if the current value is DIFFERENT than the one you just read...
          if (currentValue != newValue) { 
            currentValue = newValue; // make them the same.
            if (newValue == 1) { // If you just set it to a 1...
              counter++; // it just finished a pulse, so add one to the counter.
            }
          }
        }
    
        lastValue = newValue; // Your new value becomes the old one for comparison.
    
      } else {
    // once the dial returns home and switches the initializing pin OFF,
    // you can be sure that there will be no more pulses coming.
    // "Counter" is the number dialed. You may now use it for whatever you want.
    // This is adjusted for the special case of "0" actually being 10 pulses.
    
        if (counter > 0 && val!=HIGH) {
          if (counter == 10) {
          Serial.println (0);
          } 
    
          else if(counter == 6) {      // if the number is six
                Serial.println("play response");             // play something
             }
          else if (counter == 7) {    // if the number is seven
                Serial.println("record"); //record
    
          }
          else {
            Serial.println (counter);
          }     
    
    // After you're done using it, reset counter so it can start again on the
    // next dial.
      counter = 0;   
      }
    
    }
    }
    

    Processing

        /*Basic rotary phone recorder and playback machine. For use with Arduino and a phone.
        *--------------------------
        *This code reads strings from Arduino and then uses the Minim player to record and playback a series of audio files
        */
    
        import processing.serial.*; 
        import ddf.minim.*;
    
    
    
        Minim minim;
        AudioInput in;
        AudioRecorder recorder; 
        AudioPlayer player;
        AudioPlayer player2; 
    
    
    
        Serial myPort;  // Create object from Serial class
        String val;     // Data received from the serial port 
    
        void setup() {
          minim = new Minim(this);
    
          in = minim.getLineIn();
          recorder = minim.createRecorder(in, "myrecording.wav"); //record audio to the file myrecording.wav in the sketch root folder
    
          player = minim.loadFile("operator.aif"); // load the operator track
          player2 = minim.loadFile("myrecording.wav"); //load the recorded file for playback (this file should exist in the folder before you open the sketch for the first time. It will be written over each time)
    
    
    
            String portName = Serial.list()[2]; //change the 0 to a 1 or 2 etc. to match your port
          myPort = new Serial(this, portName, 9600); 
    
        }
    
        void draw()
        {
    
        background(0);
    
        readSerial(); //read the data coming from arduino
    
        if (val.equals("play operator")){  //if you get the string for operator, play that file
              player.play();
              println("playing operator");
    
        }
    
         if (val.equals("stop operator")){ //if you got the sign to shut up, do so:
    
            player.pause(); //silence the operator 
            player.rewind(); //go back to the beginning of the song
            player2.pause(); // silence the recorded file
            player2.rewind(); // rewind the recorded file
    
           if ( recorder.isRecording() ) // if the recorder is still going, close it and save the file
            {
              recorder.endRecord();
              recorder.save();
            }
            println("shhhh");
         }
    
          if (val.equals("play response")){ //if you get the sign to play the recorded file, do so
            player2.play();
            println("playing recorded message");
          }
    
          if (val.equals("record")){  //if you get the sign to record, do so
            println("recording message");
            recorder.beginRecord();
          }
    
    
    
        }
        void readSerial(){
             do{
            val = myPort.readStringUntil('\n');         // read incoming data and store it in val 
            } while (val == null);
          val=trim(val);
    
          }
    
Sign In or Register to comment.