psychopy.org | Reference | Downloads | Github

Question: connecting arduino with psychopy

Hi, I’m new to Python and PsychoPy, and I plan to set up the communication between Arduino Uno and PsychoPy through pyserial using the custom code element. I have tested the code in Arduino and Python3, and everything went well. However, when I use the PsychoPy, it returns no result. So, quite desperate right now.

The code for Arduino:
void setup() {
pinMode(12,OUTPUT);
Serial.begin(9600);
}

void loop() {
if(Serial.available()>0)
{
char input=Serial.read();
if(input==‘1’){
digitalWrite(12,HIGH);
delay(1000);
digitalWrite(12,LOW);
Serial.print(“The Device was on”);
}
else if(input==‘0’){
digitalWrite(12, LOW);
}
}
}

The code for PsychoPy:
import serial
port=serial.Serial(‘COM3’,9600)
port.write(‘1’) //as I have installed python3, the code I run through cmd is port.write(b’1’)
port.close()

Any help will be much appreciated!

Many thanks,
Tongyu

Hello,

In your arduino program change char input = Serial.read(); to int input = Serial.read();

Edit: I should also give a comprehensive example on the Python side of things. It also looks like some data is being passed back to the host PC and you might want to also use that.

import serial
import time

def main():
    # open the port
    port = serial.Serial("COM3", 9600)

    # by default, the Arduino resets on connection,
    # give it some time to wake-up.
    time.sleep(1)

    # write data to the port
    port.write('1')
    port.flush()

    # blocks until a response arrives (synchronize CPU<->MCU actions)
    while not port.inWaiting():
        print(port.readline())

    # close, we are done with the port
    port.close()
    return 0

if __name__ == "__main__":
    main()

Furthermore in Arduino, change Serial.print("The Device was on"); to Serial.println("The Device was on"); since port.readline() expects an end-line character.

2 Likes

Thanks, but I still have the same problem that it doesn’t work on PsychoPy(I use a LED to test the code, and it didn’t blink).
I have changed it into int input = Serial.read(); , and as Serial.print is just for me to test if the code works, so I change the Arduino code into:

void setup() {
 pinMode(12,OUTPUT);
 Serial.begin(9600);
}

void loop() {
  if(Serial.available()>0)
  {
    int input=Serial.read();
    if(input=='1'){
      digitalWrite(12,HIGH);
      delay(1000);
      digitalWrite(12,LOW);
      }
     else if(input=='0'){
      digitalWrite(12, LOW);
      }
    }
}

As for the part in PsychoPy, I have adapted it as:

import serial
import time

port = serial.Serial("COM3", 9600)
time.sleep(1)
port.write('1')
port.flush()
port.close()

So did I again make any mistake on the code?

I understand the time.sleep(1) part, and the port.flush() part. And I didn’t use the main() because I plan to add the code

import serial
import time

port = serial.Serial("COM3", 9600)
time.sleep(1)

at the very beginning of the experiment, and for each trial, administrate the stimulus using port.write('1') and port.flush(), and at the end of the experiment using port.close().

Hello,

I burned the program onto an Arduino myself and it seems to work. Even with the Python code you provided I was able to make an LED switch on for a second with ‘1’ and suppress it with any other character.

A bit of a long-shot, try the following:

  1. Use pin 13’s LED instead of 12 (marked on the board with an ‘L’) to see if you can get that one to blink.

  2. Use the ASCII decimal value for the command instead of the character.

if(input=='1'){ -> if(input==49){ and
else if(input=='0'){ -> else if(input==48){

Good luck.

Thanks, I just tried it again, and it seems like that I didn’t get it right because I used to insert the code in the wrong place. When I insert the code

import serial
import time

port = serial.Serial("COM3", 9600)
time.sleep(1)

in the script compiling view of the builder’s mode, right under the

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
This experiment was created using PsychoPy2 Experiment Builder (v1.84.2),
    on 2017_05_11_0104
If you publish work using this script please cite the PsychoPy publications:
    Peirce, JW (2007) PsychoPy - Psychophysics software in Python.
        Journal of Neuroscience Methods, 162(1-2), 8-13.
    Peirce, JW (2009) Generating stimuli for neuroscience using PsychoPy.
        Frontiers in Neuroinformatics, 2:10. doi: 10.3389/neuro.11.010.2008
"""

from __future__ import absolute_import, division
from psychopy import locale_setup, gui, visual, core, data, event, logging, sound
from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
                                STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)
import numpy as np  # whole numpy lib is available, prepend 'np.'
from numpy import (sin, cos, tan, log, log10, pi, average,
                   sqrt, std, deg2rad, rad2deg, linspace, asarray)
from numpy.random import random, randint, normal, shuffle
import os  # handy system and path functions
import sys  # to get file system encoding

it works perfectly, but I don’t know how to compile it in the coder’s mode correctly. Maybe that’s way I can’t get a good feedback before. Still, don’t really know the reason for that.