I have written a program for controlling my AH3-R Botboarduino SSC-32 hexapod. I poll the PS2 at the beginning of the loop() function. It works OK except that it does not reliably respond to commands from the PS2. I have to catch it just right. I have been playing around using interrupts to get the controller input, but with no luck. I switched the DAT, CMD, ATT connections from pins 6, 7, 8 to pins 2, 3, 4, so that I might sense interrupts 0 or 1 (pins 2 or 3) and that works OK when polling the PS2. However, the program seems to hang when I try to use interrupts. I enable interrupts with an attachInterrupt statement in setup() which refers the PS2 routine I use for reading it.
Is it possible for me to use interrupts to read the PS2?
Tried to send the files, but ran into a problem. The system says it won’t let me upload a .ino file. I copied the file into another folder and renamed it. Still got the message saying .ino files are not allowed, and the file does not appear to have been uploaded. I can’t see how the system determined it once was a .ino file.
My code is pretty simple. In setup() I initialize things. In the loop() function, the first thing I do is call a routine getInput() which reads the PS2, and then do things to control the robot. It all works OK using polling. However, adding attachInterrupt(interruptOnPin_2, getInput, CHANGE) in setup() and commenting out the getInput() routine in loop(), does not work.
Let’s leave this. If you get any thoughts on how to use interrupts to read the PS2 controller, please let me know. If it is possible, there must be some general principals involved. In the meantime I’ll use polling.
Two choices for upload: either put into zip file, which is easy, In Arduino IDE go to the Tools menu and choose the Archive sketch, which will do this for you. Or if short, just cut and paste the program into the forum. But if you do it that way, please put into code block. On this forum on advanced editing or the like, there is a button called code, which creates the proper tags. Simply put your code between them. On some other forums, the button appears to be marked as #
We’d have to see your modified code for sure, but if your getInput() function has all the logic of checking each button state and making any control changes, it can’t be used as an Interrupt-Sub-Routine (ISR) because it is doing way too much for something that would be triggered every time the data signal changes from low to high or back. Instead, you would want your ISR to shift in bits into a buffer and when the buffer is full, run the control logic. This would be a LOT of work to implement.
To double-check, have you removed the JPU, JA, JB, and JC jumpers from your BotBoarduino board? They sometimes interfere with the PS2 data if left installed.
Also, we’ve changed the forum settings to allow INO files as attachments.
I’ve attached the zipped file. Thank you for the tip on how to do that. I learn things every day.
By way of explanation, even though my robot is round I configure the legs to be normal (perpendicular) to the fore-and-aft axis of the robot for walking straight. For turning I configure the legs to be in radial positions as one might expect for a round robot. Also, I intentionally use a verbose style of programming, preferring code readability over code brevity.
I don’t mind if anyone finds any of this code useful and wants to use it in any way.
Not sure exactly what you are trying to do with the interrupt here. Are you wanting some external interrupt to come in, which you then read from the PS2? That is sort-of what I see in your code.
But there are issues with this including. The documentation for attachInterrupt says:
But if you look at the read_gamepad, it is using delays and timers and the like, so probably issue there.
LIkewise if you are doing a complete PS2 input sequence on an interrupt, this can take awhile and you may lose other interrupts. Example if serial data is coming in on the hardware serial port, if you don’t service this interrupt before another character is received, some characters will be lost.
I would like to be able to get new PS2 input by using an interrupt rather than by polling. I have timed the routines for reading the PS2, and they take only a couple of ms. I am coming to the conclusion that it is not possible to use interrupts with the existing PS2 software. Thank you for your help and explanations.
Yep - The PS2 controller is a polled device. More specific it is a slave device on an SPI network, where the Arduino is the master. I probably already pointed this out, but more details on how the controller works can be found up at: store.curiousinventor.com/guides/PS2
What I have not tried, and don’t know how well it would work, is trying to use the hardware SPI on the Atmega328 instead of bitbanging it. On Atmega the SPI pins are 10-13. You can first try with the SPI library: arduino.cc/en/Reference/SPI#.UyMIkFe1vQs If you can get this to work, then you potentially then update it to instead of waiting for each byte to be transferred (SPI.transfer), you can update the hardware registers directly and enable transfer interrupt, and then setup the code in some form of state machine, that once you start a PS2 transfer (output an 0x01), when you get the interrupt you output the next byte…
But you then still need to setup some way to kick it off. Could be through the use of a timer…
Thank you for all the time you’ve put in on this. If I get anywhere with this, which is unlikely, I’ll let you know. Thanks to you, I know a lot more than I did before.