1

I'm trying to communicate between a program on the Arduino Uno and a program on the PC via USB. I got it more or less working. Only problem is that it doesn't work when I run my PC program the first time after I upload the Arduino code via the Arduino IDE (version 2:1.0.5+dfsg2-4). It has some strange behaviour. Of course I could do some workaround, but I hope someone knows what the cause of this problem is and if there is a nice way to solve it.

This program should send back every byte it receives:

void setup () {
    Serial.begin(9600);
    while (!Serial) {}
}

void loop () {
    if (Serial.available()) {
        Serial.write(Serial.read());
    }
}

This program sends the bytes 0 to 255 to the Arduino twice and outputs every byte it receives. It is written in Scala and uses the Java RXTX library for serial communication. I'm using Debian Linux.

import gnu.io.CommPortIdentifier
import gnu.io.SerialPort

object SerialTest extends App
{
    val portId = CommPortIdentifier.getPortIdentifier("/dev/ttyACM0")
    val port = portId.open(getClass.getName, 0).asInstanceOf[SerialPort]
    port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE)

    val in = port.getInputStream
    val out = port.getOutputStream

    for (i <- 0 until 512) out.write(i)

    while (true) print(in.read + " ")
}

Instead of the 512 bytes it should receive, only around the last 44 bytes are received. Also, the first bytes the program receives are usually wrong. When I run the program for a second time, I get the desired result.

  Try 1: 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
  Try 2: 186 58 93 157 221 29 151 167 183 199 215 231 247 7 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
  Try 3: 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
  Try 4: 221 29 151 167 183 199 215 231 247 7 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 
Desired: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255

If I let the program wait for 2 seconds anywhere between val portId = ... and writing to the output stream, it works. But there is be a better way, right?

(related question)

6
  • If you say that another question "is more or less the same" then your question should be closed as a duplicate. To have a new question, you need instead to explain how yours is different. Oct 15, 2016 at 17:13
  • It is not clear what exactly your problem is, but you might consider either putting several seconds delay between the opening of the serial port and the attempt to communicate in order to allow the bootloader to time out, or better looking for an echo of test data before real data, or changing the serial port configuration to disable the modem status line manipulation on open which triggers reset, or change the wiring of the board or remove the bootloader. Also fully configure the advanced serial port settings, rather than merely hoping whatever last used it set what you want. Oct 15, 2016 at 17:17
  • Why have <while(!Serial)> when you use an UNO??
    – Dat Ha
    Oct 15, 2016 at 17:44
  • The only "better way" than a delay is a delay followed by a positive verification of communication and repeate if necessary until success, as already mentioned. Or else to prevent the reset in the first place, but that is chancy as it depends on a modification that might not be made in every case. Oct 15, 2016 at 18:58
  • 1

1 Answer 1

1

The first time you open the serial port on the PC the Uno resets and enters the bootloader. Two seconds later your sketch starts running.

By then you have already sent a load of your data to the Uno which it ignores because it's not valid bootloader commands.

When your program exits it leaves the port in an different state (RXTX is crap and doesn't clean up after itself when you terminate a program). That state includes the DTR signal being disabled.

With the DTR signal disabled the Uno doesn't reset when you open the port. Thus when you run your program a second time the sketch is already running and everything works fine.

You can toggle the control of the DTR signal in Linux by setting or clearing the hupcl flag on the tty:

Disable DTR control:
$ stty -F /dev/ttyACM0 -hupcl

Enable DTR control:
$ stty -F /dev/ttyACM0 hupcl

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.