Asset - Extension Arduino DLL

Buff

Member
It's back!

Here is the link to the old GMC topic.


I finally got around to fixing the Arduino DLL, it should now work with no problems on Windows 10 in GM:S and GM8.

This DLL allows you to connect to multiple Arduino microcontrollers and read and write data to them. I have successfully tested it with an Arduino Uno. Here is a list of the available functions:

arduino_create(com, baud) - Creates a new Arduino connection and returns the id.

arduino_connected(id) - Checks to see if an Arduino is connected.

arduino_read(id, length) - Reads a string of a certain length from the Arduino.

arduino_read_to(id, char) - Reads to a delimiter character and returns the read string.

arduino_read_line(id) - Reads to the end line character.

arduino_write(id, buffer, length) - Writes a string to an Arduino.

arduino_delete(id) - Destroys the connection to the Arduino, freeing it from memory.

arduino_destroy() - Destroys the connection to all Arduinos and frees them from memory.

Update 1.0.1
Added the ability to set the baud rate in the arduino_create function.

Here is a link to the Marketplace Asset.

And here is a download link which you can use without the marketplace, it also includes the example Arduino code, the GM8 gmk, and the C++ source code.

Enjoy,
Buff
 
Last edited:

Buff

Member
is there a way to write bytes and reals?
Technically it writes a char array on the C++ side, you can interpret that char array in any way you wish on the Arduino side, you can use Serial.read() to read the next byte from the input buffer. You could, in theory, send any kind of data as a char array, four chars make an int, eight make a double, you would have to concatenate them as a string in GM and them parse them on the other side in Arduino. This would be a bit of a pain of course. Arduino does however have the built in Serial.parseInt() and Serial.parseFloat() functions to help convert strings to reals however. I may add convenience functions to write other data types if I find the time, the source is available too if you want to give it a shot.
 

hippyman

Member
I'll be honest, I'm not really sure what I would do with this. But it's interesting. Do you have any examples on what this could be used for?
 
V

vo.linh.truc

Guest
Thanks you thanks you so so MUCH!!!
I'm waiting for this so long !!!
I'm very tried when i try to find the answer that "Why the Led13 doesn't OFF?".
Now with this post, I'm very happy !!!
So thanks you again.
Can I Add friend you on facebook ?
How can I find you !?
 

meliaz99

Member
Aww yeah!
Finally! Thank you so much @Buff!

Anyway I'm currently thinking about creating a GM+Arduino tutorial if anyone interested. :)

I'll be honest, I'm not really sure what I would do with this. But it's interesting. Do you have any examples on what this could be used for?
About a year ago I created something like this, playing GameMaker games using light sensors!

Sadly I currently now away from Arduino and stuff, but planning creating new stuff if I got time!

Thank you Buff, you are our hero :D
 
V

vo.linh.truc

Guest
I can't convert the data in as String to real to caculate.
Pls help !!!
It have an error in "real" function !!
 

Buff

Member
I can't convert the data in as String to real to caculate.
Pls help !!!
It have an error in "real" function !!
Is this on the GM side or the Arduino side? Have you tried printing out the value to make sure it's a valid number? Can I see the error and the code that is causing it?
 

slayer 64

Member
It have an error in "real" function !!
In my experience, serial connections and strings are a real pain. The arduino string functions are a little slow. I ended up writing bytes and decoding messages instead of using strings which take up more space and calculations anyway.

Sounds like you could use string_digits() to remove strange characters before passing the string to the real() function.
 

FHD

Member
Can this help to develop and play Game Maker games on Arduino devices ?
I am not sure if there is any standard Arduino device to do so...tell me about it.
 

Nexusrex

Nexusrex Games
Can this help to develop and play Game Maker games on Arduino devices ?
I am not sure if there is any standard Arduino device to do so...tell me about it.
Well, as far i know. This is made to help you doing something of 2 things:
1- Control GM games by the Arduino
2- Control the Arduino by GM games
 

Buff

Member
Can this help to develop and play Game Maker games on Arduino devices ?
I am not sure if there is any standard Arduino device to do so...tell me about it.
If you mean run the game on an Arduino device, then no this is not possible.
This merely opens up a communication connection between the Arduino and your game.
 
B

Bobby K

Guest
Awesome work! i have been waiting for this to work for so long! (Rather than use GM8).

What i am wondering is if there is a way to modify the baud rate. i noticed it is at 9600 however for the project i have been waiting to use this in i require at min 57600bps. preferably 115200.

(In the arduino code it is simple to modify, it is the GM dll i am wondering if there is an additional argument to specify the baud rate of the connection)

Thanks
 

Buff

Member
Awesome work! i have been waiting for this to work for so long! (Rather than use GM8).

What i am wondering is if there is a way to modify the baud rate. i noticed it is at 9600 however for the project i have been waiting to use this in i require at min 57600bps. preferably 115200.

(In the arduino code it is simple to modify, it is the GM dll i am wondering if there is an additional argument to specify the baud rate of the connection)

Thanks
You're right, this is something I should have done originally. I have updated the library to include setting the baud rate in the arduino_create function like so, arduino_create(com, baud).
I updated the forum post, the asset, and the direct download.

Thank you for your feedback and I hope your project goes well.
 
C

Christophe Richard

Guest
Hey buff,

I'v been having trouble lately figuring out two things in your arduino gml dll :
In arduino, What does the char buff [2]="" is here for ? For example if i want to send 1,2,3 and 4 at the arduino board, i must to modify the array by the char buff[4]:"" ?
In GML, How could you explain The need to add +1 for The "nulle terminator"?

Thanks !
 

Buff

Member
Hey buff,

I'v been having trouble lately figuring out two things in your arduino gml dll :
In arduino, What does the char buff [2]="" is here for ? For example if i want to send 1,2,3 and 4 at the arduino board, i must to modify the array by the char buff[4]:"" ?
In GML, How could you explain The need to add +1 for The "nulle terminator"?

Thanks !
The char buff[2] bit is not used, it was from an old example where I read the bytes individually, I must have forgotten to remove it. In this example the values are read using Serial.parseInt() instead.

Most languages, including GML, denote the end of a string with an extra character, the null character (represented by a \0). This tells the computer where to stop reading the string in memory, these are called null terminated strings. Arduino reads the data as char arrays, this is basically the same thing as a string, a list of characters. When sending data to an Arduino you must tell it how many chars you are going to send so that it knows what to expect, but when counting the chars GM does not include the null terminator in the string_length function, only the characters you see are included, but it will send all of those characters plus the null terminator. The Arduino will not be expecting this last char and will crash as a result. This is why you must tell it to expect one more character, because the null character will be sent along with the rest of your string.

You can read a bit more about Arduino and strings here.

Buff
 
V

Victor916

Guest
Hi everyone,

I'm new in GameMaker and I want to do something with arduino and this DLL, but I've tried and I can't connect arduino with GM. So, could anyone show me a simple script? For example, at first I have tried to turn on pin 13 in arduino and nothing happened :confused:

Sorry for my ignorance and thanks!! :)
 
R

Rumpelcita

Guest
I'm having an issue on gm side. I'm trying to read the data from a light sensor, but I'm not getting updated data on gm when I activate a light source close to the sensor. I get old sensor data and sometimes I also get garbage:
Code:
����Qp� ��
114
����]p� ��
114
���������������'^�
113 112
With a light source pointed towards it, the sensor reads more than 200 on the arduino console, so it's weird. What am I missing?

I made an object with this create:
Code:
ard = arduino_create("COM4", 115200)
Then I added this to the step event:
Code:
result = arduino_read_line(ard)
show_debug_message(result)
The arduino code, just in case:

Code:
//pin definitions
#define PHOTOCELL 0 //photocell analog in pin 0

//variable definitions
long val = 0;        //stores raw value from photocell
int i = 0;            // loop dummy variable
                            
void setup()
{
  Serial.begin(115200);
  pinMode(PHOTOCELL, OUTPUT);
}

void loop()
{
  val = analogRead(PHOTOCELL);   // read photocell
  Serial.println(val,DEC);
  delay(1);
}
 
I'm having trouble with this as well. Trying to read a line from withing Game Maker and it is like 10 seconds behind when Arduino itself prints it. Also, sometines my game returns a whole lot of weird characters. I tried the example you provided but same issue. Please, I would appreciate any help. You're doing a great job. Keep it up!

My problem seems similiar to that of Rumpelcita.
 
Last edited:
B

Bobby K

Guest
I'm having an issue on gm side. I'm trying to read the data from a light sensor, but I'm not getting updated data on gm when I activate a light source close to the sensor. I get old sensor data and sometimes I also get garbage:
Code:
����Qp� ��
114
����]p� ��
114
���������������'^�
113 112
With a light source pointed towards it, the sensor reads more than 200 on the arduino console, so it's weird. What am I missing?

I made an object with this create:
Code:
ard = arduino_create("COM4", 115200)
Then I added this to the step event:
Code:
result = arduino_read_line(ard)
show_debug_message(result)
The arduino code, just in case:

Code:
//pin definitions
#define PHOTOCELL 0 //photocell analog in pin 0

//variable definitions
long val = 0;        //stores raw value from photocell
int i = 0;            // loop dummy variable
                          
void setup()
{
  Serial.begin(115200);
  pinMode(PHOTOCELL, OUTPUT);
}

void loop()
{
  val = analogRead(PHOTOCELL);   // read photocell
  Serial.println(val,DEC);
  delay(1);
}


Try amd lower the baud rate for starters. 9600 is well and truely enough for testing what your doing for now :) you also minimize problems when your troubleshooting. also, photocells are inputs not outputs. so try and change the pinMode to INPUT.

I will be reading digital switches on an arduino and sending to game maker soon. i have a photo resistor so ill have a play with it and see if i can read the data in game maker and post my results.

Hope this helps a little.
 
I need to send 2 simple commands over the serial port (not to an arduino - but this is the only module that is close to a serial dll) and am finding it very difficult to get it to work.

I need to send the following:
Char: 254, 001
or Hex: FE, 01

and then later:
Char: 254, 002
or Hex: FE, 02

Tried the following (converting the hex to string) with no luck.
Code:
res = arduino_write(ard, string($FE), 2);
res = arduino_write(ard, string($01), 2);
Do you have any ideas how to accomplish this? I don't have any control over the device I am sending to, otherwise it would be an easy fix. If we could send the hex code directly that would solve all issues.

PS. I have the same issues as above with receiving data (overrun with trash). Sending is fine, however (which is all I need).
 

Buff

Member
I need to send 2 simple commands over the serial port (not to an arduino - but this is the only module that is close to a serial dll) and am finding it very difficult to get it to work.

I need to send the following:
Char: 254, 001
or Hex: FE, 01

and then later:
Char: 254, 002
or Hex: FE, 02

Tried the following (converting the hex to string) with no luck.
Code:
res = arduino_write(ard, string($FE), 2);
res = arduino_write(ard, string($01), 2);
Do you have any ideas how to accomplish this? I don't have any control over the device I am sending to, otherwise it would be an easy fix. If we could send the hex code directly that would solve all issues.

PS. I have the same issues as above with receiving data (overrun with trash). Sending is fine, however (which is all I need).
Stringifying a hexadecimal number will give you the string representation of the number. arduino_write(ard, string($FE), 2) will send "254" that is three bytes, 50, 53, and 52.

What you want to do is send the character representation of the numbers:
Code:
res = arduino_write(ard, chr($FE), 2);
res = arduino_write(ard, chr($01), 2);
This will send the bytes 254 and 1. The null character will also be sent in between and after the two bytes, which your device may not be expecting, so it actually sends 254, 0, 1, 0. You can mitigate this by sending the bytes side by side:
Code:
res = arduino_write(ard, chr(254) + chr(1), 3);
This will send 254, 1, 0. Hopefully your device takes the bytes in pairs and will just ignore the null character at the end. Unfortunately the DLL does not support sending strings without the null character.
 
Nice, thanks for the help. I will give it a go right now!

EDIT: I receive 195, 011 using comDebug using the above code. Stumped.
 
Last edited:
It's back!

Here is the link to the old GMC topic.


I finally got around to fixing the Arduino DLL, it should now work with no problems on Windows 10 in GM:S and GM8.

This DLL allows you to connect to multiple Arduinos microcontrollers and read and write data to them. I have successfully tested it with an Arduino Uno. Here is a list of the available functions:

arduino_create(com, baud) - Creates a new Arduino connection and returns the id.

arduino_connected(id) - Checks to see if an Arduino is connected.

arduino_read(id, length) - Reads a string of a certain length from the Arduino.

arduino_read_to(id, char) - Reads to a delimiter character and returns the read string.

arduino_read_line(id) - Reads to the end line character.

arduino_write(id, buffer, length) - Writes a string to an Arduino.

arduino_delete(id) - Destroys the connection to the Arduino, freeing it from memory.

arduino_destroy() - Destroys the connection to all Arduinos and frees them from memory.
Sorry to revive this thread, but I just ordered an Arduino to check out this .dll file :) If I want to set a pin HIGH, though GM:S, what code should I use? I am thinking 'arduino_write()' but how do I choose pin number etc? I just need to be able to set a pin to +5V and 0V.

Thanks!
 
B

Bobby K

Guest
Sorry to revive this thread, but I just ordered an Arduino to check out this .dll file :) If I want to set a pin HIGH, though GM:S, what code should I use? I am thinking 'arduino_write()' but how do I choose pin number etc? I just need to be able to set a pin to +5V and 0V.

Thanks!
you dont directly send commands. this dll will let you send data over serial, so you can tell GM:S to send a number then on the arduino side read it and do something. if you scroll up you can see some examples :)
 
So, when the code is made for the Arduino, it is stored in the device? If I assign a pin as output, does it stay in the unit, or only while the code is running from the PC?
 

Buff

Member
So, when the code is made for the Arduino, it is stored in the device? If I assign a pin as output, does it stay in the unit, or only while the code is running from the PC?
Hi,
This DLL assumes you have some working knowledge of Arduino programming. The code that actually controls the device is written in the Arduino programming language, this DLL just opens up a communication line between Game Maker and your Arduino. The tutorials on the Arduino website are very good and can help you get started. There are lots of resources online that can show you how to do all kinds of things with Arduinos, you should figure out how to set a pin to HIGH in Arduino and then use the example from this DLL to learn how to trigger it with Game Maker.

Buff
 
E

Elsewhere

Guest
Hi, I'm having some problems with reliability. I think it has something to do with reading starting or ending between character boundaries, but that's just a guess. I'm currently using the sample program to get orientation values from an arduino and my output looks like this (concatenating results sequentially here):

(EDIT: fixed my concatenation code, so it's a lot cleaner. Some issues are still visible, though)


Obviously, the data is supposed to be formatted a specific way, but some junk is getting in the way. The amount of garbage I get depends on which function I use. This one was using arduino_read(ard,100), but I've gotten varying results with arduino_read_line and arduino_read_to, all with this inconsistency issue. The communication is via COM3, 9600 baud. I do not encounter this issue with any other serial application (I've used pySerial, CoolTerm, Inbetwino, and of course Arduino serial monitor), so I can attest to my side of things working properly.

Here's my concatenation code, by the way. The issue still occurs if just reading the strings out rapid-fire, this just makes it easier to catch.

Code:
var newresult; newresult = arduino_read(ard,100)

if newresult != "" {
    result += newresult;
    data = string(result)
    }
   
if keyboard_check_pressed(ord('X'))
result = "";
So, any ideas to fix this issue? Thanks in advance.
 
Last edited by a moderator:

Buff

Member
Hi, I'm having some problems with reliability. I think it has something to do with reading starting or ending between character boundaries, but that's just a guess. I'm currently using the sample program to get orientation values from an arduino and my output looks like this (concatenating results sequentially here):

(EDIT: fixed my concatenation code, so it's a lot cleaner. Some issues are still visible, though)


Obviously, the data is supposed to be formatted a specific way, but some junk is getting in the way. The amount of garbage I get depends on which function I use. This one was using arduino_read(ard,100), but I've gotten varying results with arduino_read_line and arduino_read_to, all with this inconsistency issue. The communication is via COM3, 9600 baud. I do not encounter this issue with any other serial application (I've used pySerial, CoolTerm, Inbetwino, and of course Arduino serial monitor), so I can attest to my side of things working properly.

Here's my concatenation code, by the way. The issue still occurs if just reading the strings out rapid-fire, this just makes it easier to catch.

Code:
var newresult; newresult = arduino_read(ard,100)

if newresult != "" {
    result += newresult;
    data = string(result)
    }
 
if keyboard_check_pressed(ord('X'))
result = "";
So, any ideas to fix this issue? Thanks in advance.
Hello Elsewhere,

I have also seen garbage make its way through the pipe, unfortunately I have yet to pinpoint the problem. My current recommendation, although rather lame, is to treat the data transfer like a network packet that correctly ignores damaged data and only uses what it knows is (or at least believes to be) healthy data. Over networking cables and wireless transfers in the real world data is lost or corrupted all the time and so it is sent via error correcting packets that can be checked for correctness and used or ignored properly. A simple way to decode your current format, only taking the good parts, might be:
Code:
//process_data(data)
//data: A line of data as a string
//Sets the local variables of x, y, and z to the values found in the data.
//returns true if successful, false if there was an error extracting the data.
var xpos, ypos, zpos, xstr, ystr, zstr;

xpos = string_pos("X: ", data)
ypos = string_pos("Y: ", data)
zpos = string_pos("Z: ", data)

if xpos == 0 || ypos == 0 || zpos == 0
    return false

xstr = string_copy(data, xpos + 3, ypos - xpos + 3)
ystr = string_copy(data, ypos + 3, zpos - ypos + 3)
zstr = string_copy(data, zpos + 3, string_length(data) - zpos + 3)

x = real(xstr)
y = real(ystr)
z = real(zstr)

return true
The real() function will throw an error if the string is not formatted like a number so you will want to do some checking above that which allows for the minus sign and decimal place. You could take your data packet even further, with a header and a CRC, if you're interested in a learning experience it might be fun to design your own packet.

But obviously the best thing to do is to fix this garbage problem. Could you post the Arduino code that is used to format and send this data? It could be a clue as to what is going on.

Buff
 

Buff

Member
Thanks for the quick reply! That's an interesting suggestion, but it is desirable to have the same reliability as all of the other serial implementations, of course.

My Arduino setup and code mirrors the test code on this page (first code chunk): https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/wiring-and-test Only appreciable difference is that I'm using a Pro Mini.
One thing that might reduce the garbage is to combine the print statements. Although the garbage does seem to appear within individual prints like with "X9:"...
Can you also check that the data in the debugger and/or the data written to a file is the same as what is printed in GM? It would be bizarre but this would rule out a potential glitch in the actual printing of the string.
 
Please do!
Well, finally got the Arduino 2560! I managed the usual sketch stuff with blinking LEDs etc, and I just tried your GM software. Works perfectly with "enter 1 to turn the LED on". But I can't seem to get my head around how I should apply the code:
Code:
arduino_write(id, buffer, length)
...if I, for example, just want to turn the LED on by just pressing 'space' or something like that. I take it that id is ard, but what is buffer and length? :)

Thanks! I was very happy to see how it just worked out of the box!
 

Buff

Member
Well, finally got the Arduino 2560! I managed the usual sketch stuff with blinking LEDs etc, and I just tried your GM software. Works perfectly with "enter 1 to turn the LED on". But I can't seem to get my head around how I should apply the code:
Code:
arduino_write(id, buffer, length)
...if I, for example, just want to turn the LED on by just pressing 'space' or something like that. I take it that id is ard, but what is buffer and length? :)

Thanks! I was very happy to see how it just worked out of the box!
arduino_write sends a string of text to the Arduino through serial communication. Buffer is the string to send and length is the length of the string plus 1. As mentioned earlier, you can't directly control the Arduino with this DLL but you can talk to it.

You could, for example, send a string to the Arduino in the keyboard press event in GM like so:
Code:
str = "turn on the LED!"
arduino_write(ard, str, string_length(str) + 1)
and then on the Arduino side read the string and do something with it:
Code:
String str = Serial.readString();
if (str == "turn on the LED!")
{
    digitalWrite(13, HIGH);
}
You will always have to write some Arduino code to interpret what the GM program is saying.
 
Thanks, that makes sense - and works. However, there's almost a full second delay between pressing the button and the LED lighting :) I can see that the Arduino receives the button press right away, though. I have no idea why :)
 

Ninnin

Member
Hi.
I see it's a DLL, so i think it won't work for android :p
Does it exist any way to make it works with android ?
My arduino must controll an android device, so i just have to treat the serial datas on my android but i don't know if it's possible with GM:S ?
 

Buff

Member
Hi.
I see it's a DLL, so i think it won't work for android :p
Does it exist any way to make it works with android ?
My arduino must controll an android device, so i just have to treat the serial datas on my android but i don't know if it's possible with GM:S ?
No, the DLL will not run on Android. You'd have to write a new extension in Java that communicated over the usb port via serial.
 

Lucky Bacon

Member
Is it normal that GM:S reads data, and shows garbage data sometimes? I haven't touched anything in the example from the downloaded .ino and .gmz, except change COM3 to COM5, and pin 13 to 11.\
If not, how do i fix that?
Arduino UNO, baud: 9600.
 

Buff

Member
Is it normal that GM:S reads data, and shows garbage data sometimes? I haven't touched anything in the example from the downloaded .ino and .gmz, except change COM3 to COM5, and pin 13 to 11.\
If not, how do i fix that?
Arduino UNO, baud: 9600.
Hey Lucky,

It's normal. It shouldn't be happening but it does and several other people have reported this same problem.

I spent a fair amount of time looking at the C++ and I cannot figure out where the corruption is coming from. It's a fairly simple interface, there's not a lot that can go wrong, but something is happening.

If you look at other posts in this thread you can see that others have had the same results. My only advice is that you somehow validate your data and throw out corrupted packets. See this post for an example.

Buff
 
M

martin_soldat

Guest
Hi

I have made a game with the arduino dll, a controller with a joystick and 2 buttons, which sends over a string at 115200 baud(seemed to work best with the game speed)
I have that problem that every time i start the game, the arduino is slow at responding. Like when i try to move my character, it has a delay on 3 seconds or more. But after 2-3 minutes, it works flawlessly. I can't seem to figure it out?
Game FPS is over 1000

Thanks in advance
 
Last edited by a moderator:
Hi

I have made a game with the arduino dll, a controller with a joystick and 2 buttons, which sends over a string at 115200 baud(seemed to work best with the game speed)
I have that problem that every time i start the game, the arduino is slow at responding. Like when i try to move my character, it has a delay on 3 seconds or more. But after 2-3 minutes, it works flawlessly. I can't seem to figure it out?
Game FPS is over 1000

Thanks in advance
I had the same problem. Would be awesome if a solution could be found, but all this stuff is beyond me :)
 
Top