RS232 from Arduino Uno not controling amplifier

I'm attempting to use an Arduino Uno and a potentiometer to control a Bijou 600 amplifier via RS232. I have a MAX3232 to convert Arduino's TTL to the amp's RS232 input, and I'm fairly confident my wiring is correct.

My current assumption is that my code is not sending the carriage return line that the amplifier expects. From the amp's automation guide:

Simple ASCII is used to issue command strings via RS232. Carriage return (0x0D) / is required to end the transmission of the command string i.e. To turn on the AccuBass, simply send bass1

Bijou volume is from 0 to 63, so to set the volume at max the bijou expects to see setvol63

If the Bijou doesn't like the code you're sending it should send back the same code you sent it with an asterisk, but I haven't figured out how to read ASCII off the receive pin.

The code includes LEDs that turn on and off in sequence with the level of the potentiometer, that works fine.

byte led_pins[10] = { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2 };  // easier to wire in reversed order

#include <SoftwareSerial.h>  // allows additional pins to act as Rx and Tx for serial commands
#define rxPin 12
#define txPin 13

SoftwareSerial mySerial(rxPin, txPin);
// Set up a new SoftwareSerial object

int pot_value = 0;  // potentiometer value
int newVol = 0;     // old volume value

void setup() {
  for (int i = 0; i < 10; i++) {
    pinMode(led_pins[i], OUTPUT);  // initialize digital pins as outputs (in order to control LEDs)
  }

  pinMode(A0, INPUT);  // set A0 as input for reading the potentiometer value

  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  mySerial.begin(19200);  // Baud rate of the Bijou 600 is 19200
  Serial.begin(19200);
}


void loop() {

  pot_value = analogRead(A0);                 // read the value of the potentiometer
  pot_value = map(pot_value, 0, 1023, 0, 63);  // map the value between 0-63, as this is the range used on the Bijou

  if (pot_value != newVol) {

    newVol = pot_value;
    mySerial.print("setvol");  // RS232 volume command for the Bijou 600 is setvolx, where x is a number between 0 and 63
    mySerial.print(newVol);
    mySerial.println();  // This combination of print+printline should send the setvol'x' command to the Bijou's RX pin.
    // according to documentation myserial.println() includes a carriage return so it should work. adding '<cr>' or '\r' did not help.


    Serial.print("setvol");
    //Serial.print(newVol);
    Serial.println(newVol);  //allows me to see the code going to the bijou in the Arduino Serial Monitor
    Serial.print("A0 is ");
    Serial.print(analogRead(A0));  // so I can know potentiometer value
    Serial.println();
  }
  // light up the corresponding LEDs
  for (int i = 0; i < 10; i++) {  // set the LEDs based on the potentiometer value
    if (pot_value <= i * 6.3) {
      digitalWrite(led_pins[i], LOW);  // LED off
    } else {
      digitalWrite(led_pins[i], HIGH);  // LED on
    }
  }
}

Convince yourself, and forum members, by posting a wiring diagram. Hand drawn is preferred, with pins and connections clearly labeled. If you are using a MAX232 module, post a link to the product page.

Please also post a link to the amplifier documentation of the communications protocol.

I haven't figured out how to read ASCII off the receive pin.

Check out the Serial Input Basics tutorial.

1 Like

Here is the Max3232: SparkFun Transceiver Breakout - MAX3232 - BOB-11189 - SparkFun Electronics
Here is their hookup diagram: Hookup-diagrams/BOB-11189/BOB-11189 hookup.jpg at master · SparkfunTechSupport/Hookup-diagrams · GitHub

And here is my wiring diagram:

I confirmed with a DMM that I have continuity between the wires running into the amp and the pins on the MAX3232. I've tried using T2/R2 instead of T1/R1, and I've tried 5V as well.

1 Like

I don't see the 5 required 0.1uF caps on the MAX3232.

Oh, it's a breakout - never mind. :flushed: That'll teach me to not just look at the schematic!

The illustration below from Sparkfun is clearer, but I think your wiring is OK. Double check pin numbers on the RS232 connector.

Serial.println() sends CR and LF. In case that LF creates a problem, send just the CR by changing this:

    mySerial.println();

to this:

    mySerial.write(0x0D);

Add some code to receive the response, if any, following the suggestions from the tutorial.

Changing println to write(0x0D) worked!

Now there's a new hiccup I'm trying to work on, where after about a minute of working, the amp stops changing volume, until randomly it decides to start working again or I re-upload the program to the Arduino.

Hopefully once I'm able to get the Rx pin working I'll figure out why that's happening .

The loop function can run over 100,000 times per second, and if there is any noise or dither in the analogRead() result, you may be swamping the amplifier MCU. How frequently does output appear on the serial monitor screen?

Yes. @lizalfoes you can test that theory by simply throwing a delay(100); into your loop() function.

If that changes the behaviour, there are different ways to throttle the loop or keep specific things form happening too often that wouldn't need the blunt tool which is delay().


    Serial.print("A0 is ");
    Serial.print(analogRead(A0));  // so I can know potentiometer value

Here it would be better to have used analogRead() once, and put the reading into a variable and print that later rather than reading again, which reading may be different to what was read previously. May make no difference here, but as habit you might start soliciting inputs once per loop and using variables set accordianly subsequent to that.

a7

That's definitely the issue

Adding a delay has made the system work without issue.

Thanks everyone for your help!

Yay! You might want to put a "solved" check mark on @jremington's post #N above for the analysis that lead to this temporary solution.

When (not if) that delay turns out to make trouble for the further development, come back here and say so, we can suggest several ways to keep the traffic low so it doesn't flood you out, while also allowing your loop to continue running freely as it is meant to do.

a7

I used the code from the Blink Without Delay example to create a delay that only affects my serial commands and not the whole loop: https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay

Hopefully this is a good longterm solution!

Excellent. My work here is done. :wink:

If you would, please post the code that you ended up with as an aid to fellow travelers.

You could move the solved mark to #7 - when we rack up 1000 solutions, we get a free UNO.

a7

/*Controling a the volume of Bijou 600 amplifier using serial from the arduino. 
Also illuminating LEDs in sequence with potentiometer. 
mySerial pins go out to MAX3232 board to convert arduino's TTL to RS232*/

//byte led_pins[10] = {2,3,4,5,6,7,8,9,10,11};              // pins for 10 LEDs
byte led_pins[10] = { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2 };  // easier to wire in reversed order

#include <SoftwareSerial.h>  // allows additional pins to act as Rx and Tx for serial commands
#define rxPin 12
#define txPin 13


SoftwareSerial mySerial(rxPin, txPin);  // Set up a new SoftwareSerial object


int pot_value = 0;  // potentiometer value
int newVol = 0;     // volume value

unsigned long previousMillis = 0;  //count milliseconds instead of using Delay function
const long interval = 100;         // 100ms is enough time to not overwhelm the Bijou's MCU


void setup() {
  for (int i = 0; i < 10; i++) {
    pinMode(led_pins[i], OUTPUT);  // initialize digital pins as outputs (in order to control LEDs)
  }

  pinMode(A0, INPUT);  // set A0 as input for reading the potentiometer value

  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  mySerial.begin(19200);  // Baud rate of the Bijou 600 is 19200
  Serial.begin(19200);
}


void loop() {
  unsigned long currentMillis = millis();      // start counting time
  pot_value = analogRead(A0);                  // read the value of the potentiometer
  pot_value = map(pot_value, 0, 1023, 0, 63);  // map the value between 0-63, as this is the range used on the Bijou

  if (pot_value != newVol && currentMillis - previousMillis >= interval) {

    newVol = pot_value;
    mySerial.print("setvol");  // RS232 volume command for the Bijou 600 is setvolx, where x is a number between 0 and 63
    mySerial.print(newVol);
    mySerial.write(0x0D);  // write(0x0D) is the correct carriage return, println() did not work.

    Serial.print("setvol");
    Serial.print(newVol);
    Serial.println();  //allows me to see the code going to the bijou in the Arduino Serial Monitor
    Serial.print("A0 is ");
    Serial.print(analogRead(A0));  // so I can know potentiometer value
    Serial.println();
    previousMillis = currentMillis;  // reset millis count, will not update again until 100ms later
  }

  // light up the corresponding LEDs
  for (int i = 0; i < 10; i++) {  // set the LEDs based on the potentiometer value
    if (pot_value <= i * 6.3) {
      digitalWrite(led_pins[i], LOW);  // LED off
    } else {
      digitalWrite(led_pins[i], HIGH);  // LED on
    }
  }
}
1 Like

Nice, THX.

If the 100 milliseconds gives you the least feel that it is sluggish, try 50 or even 25. 50 would might still feel sluggish to ppl who operate at a higher frequency than I, 25 would prolly keep anyone happy.

You might be able to hear the volume changing in large steps, larger with the lower update frequency. Another problem with solutions.

Fun!

a7

100ms is actually perfect, the volume adjustment sounds smooth, and even if the potentiometer is turned to a point where it's repeatedly sending out commands, it doesn't overwhelm the amp's processor.

Really? Wow!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.