Asset - Extension Arduino DLL

Discussion in 'Marketplace' started by Buff, Jun 27, 2016.

Tags:
  1. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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: Aug 6, 2019
  2. slayer 64

    slayer 64 Member

    Joined:
    Jun 26, 2016
    Posts:
    69
    is there a way to write bytes and reals?
     
  3. Nexusrex

    Nexusrex Nexusrex Games

    Joined:
    Jun 20, 2016
    Posts:
    211
    Finally, i can use my arduino (with piezo) on GMS!
     
  4. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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.
     
  5. hippyman

    hippyman Member

    Joined:
    Jun 20, 2016
    Posts:
    565
    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?
     
  6. vo.linh.truc

    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 !?
     
  7. meliaz99

    meliaz99 Member

    Joined:
    Jun 21, 2016
    Posts:
    2
    Aww yeah!
    Finally! Thank you so much @Buff!

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

    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
     
  8. hippyman

    hippyman Member

    Joined:
    Jun 20, 2016
    Posts:
    565
    I forgot about that video! I guess that would be kind of cool to come up with some new ways to play games.
     
  9. Moon Goat

    Moon Goat Member

    Joined:
    Jun 20, 2016
    Posts:
    42
    This allows for so many possibilities, from motion detecting games to moving speakers for extended ambiance!
     
    hippyman likes this.
  10. vo.linh.truc

    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 !!
     
  11. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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?
     
  12. slayer 64

    slayer 64 Member

    Joined:
    Jun 26, 2016
    Posts:
    69
    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.
     
  13. FHD

    FHD Member

    Joined:
    Jun 21, 2016
    Posts:
    56
    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.
     
  14. Nexusrex

    Nexusrex Nexusrex Games

    Joined:
    Jun 20, 2016
    Posts:
    211
    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
     
  15. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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.
     
  16. FHD

    FHD Member

    Joined:
    Jun 21, 2016
    Posts:
    56
    I understand. Thanks guys for your response.
     
  17. Bobby K

    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
     
  18. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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.
     
  19. 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 !
     
  20. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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
     
  21. Victor916

    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!! :)
     
  22. Rumpelcita

    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);
    }
    
     
  23. Joel Sandberg

    Joel Sandberg Member

    Joined:
    Jun 21, 2016
    Posts:
    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: Sep 28, 2016
  24. Bobby K

    Bobby K Guest

    How do you delete a post :)
     
  25. Bobby K

    Bobby K Guest



    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.
     
  26. VanillaFrog

    VanillaFrog Member

    Joined:
    Jun 22, 2016
    Posts:
    10
    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).
     
  27. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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.
     
  28. VanillaFrog

    VanillaFrog Member

    Joined:
    Jun 22, 2016
    Posts:
    10
    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: Dec 7, 2016
  29. sparklemotion

    sparklemotion Member

    Joined:
    Nov 3, 2016
    Posts:
    75
    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!
     
  30. Bobby K

    Bobby K Guest

    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 :)
     
  31. sparklemotion

    sparklemotion Member

    Joined:
    Nov 3, 2016
    Posts:
    75
    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?
     
  32. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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
     
  33. sparklemotion

    sparklemotion Member

    Joined:
    Nov 3, 2016
    Posts:
    75
    Thanks, I can't wait to try it! I will report back (if that is OK)
     
  34. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    Please do!
     
  35. Elsewhere

    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)
    [​IMG]

    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: Feb 28, 2017
  36. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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
     
  37. Elsewhere

    Elsewhere Guest

  38. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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.
     
  39. sparklemotion

    sparklemotion Member

    Joined:
    Nov 3, 2016
    Posts:
    75
    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!
     
  40. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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.
     
  41. sparklemotion

    sparklemotion Member

    Joined:
    Nov 3, 2016
    Posts:
    75
    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 :)
     
  42. Ninnin

    Ninnin Member

    Joined:
    Jan 27, 2017
    Posts:
    15
    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 ?
     
  43. Mool

    Mool Member

    Joined:
    Nov 6, 2016
    Posts:
    113
    I have written an app (GMS +Extension), that could connect to an arduino via Bluetooth
     
  44. Ninnin

    Ninnin Member

    Joined:
    Jan 27, 2017
    Posts:
    15
    Thanks but only a cable connection is possible :-/
     
  45. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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.
     
  46. Lucky Bacon

    Lucky Bacon Member

    Joined:
    Nov 30, 2016
    Posts:
    14
    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.
     
  47. Buff

    Buff Member

    Joined:
    Jun 26, 2016
    Posts:
    63
    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
     
  48. martin_soldat

    martin_soldat Member

    Joined:
    Mar 15, 2018
    Posts:
    4
    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: Apr 15, 2018
  49. sparklemotion

    sparklemotion Member

    Joined:
    Nov 3, 2016
    Posts:
    75
    I had the same problem. Would be awesome if a solution could be found, but all this stuff is beyond me :)
     
  50. emanuelsko

    emanuelsko Member

    Joined:
    Jun 22, 2016
    Posts:
    5
    This is great. I wonder if I can control my 3D printer with this extension.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice