• alexandros

    You can also use shift registers for increasing the digital inputs (or outputs) of the Arduino. I've written a tutorial on the communication between the Arduino and Pd, you can find it here (it's called "Arduino for Pd'ers). The last chapter covers shift registers.

    posted in I/O hardware diyread more
  • alexandros

    This was the last version of [pduino] I know it was supported, but still in the GitHub page the last update was four years ago. Never saw the compiled object you posted before.

    posted in news read more
  • alexandros

    That did it! Thank you!

    posted in pixel# read more
  • alexandros

    @ddw_music it does include some abstractions which encapsulate an [ofelia d] object with a Lua script, like [ofSetup] for example. Haven't gone through it exhaustively though.

    posted in pixel# read more
  • alexandros

    Using Serial.print() can be tricky as it outputs ASCII values and not raw bytes, like Serial.write() does. I have written an abstraction to be used with [comport] and Serial.print(), it's called [serial_print] and you can get it here https://github.com/alexdrymonitis/Arduino_Pd
    Read the Readme first as you'll might need to use [serial_print13] instead. Also read the Arduino code to see how to format your Arduino data. It's really easy to use this.

    posted in technical issues read more
  • alexandros

    There's no vanilla way to have the Arduino talk straight to Pd. You either have to use [comport] (which is recommended), or use some other software to receive data from the Arduino (like Python) and send that to Pd over OSC.

    posted in technical issues read more
  • alexandros

    For single binary libraries you need both the path and startup, or you can [declare] them, first -path and then -lib.

    posted in technical issues read more
  • alexandros

    I've modified some abstractions created by @60hz for prototyping fast with ofelia (BTW, thanks a million for your abstractions they're great! And of course a million thanks to @cuinjune for creating Ofelia!). Things seem to work OK, but there's this happening. I have the following patch (I've changed the names from [gl.draw] to [ofelia.draw] for this and other abstractions)

    [ofelia.draw]
    |
    [ofelia.cube]
    

    and I see a white cube in the Ofelia window. Then I make the following connections:

    [ofelia.draw]
    |
    [ofelia.movie]
    |
    [ofelia.cube]
    

    and I get a video playing in the same cube. Till now everything is fine. But if I go back to the first patch, I don't get a white cube anymore but a still from the video file from [ofelia.movie]. Here are the scripts of the abstractions (almost identical to @60hz abstractions):
    [ofelia.draw] (I'm returning ofColor because I want to have all abstractions output pointers and not bangs, maybe there's a better solution for this):

    ofelia d draw$0;
    local c = ofCanvas(this);
    local args = c:getArgs();
    local depth = true;
    local screenwidth;
    local screenheigh;
    local widthHeigh;
    ;
    function M.new();
      if args[2] == nil then depth = true;
      else;
      M.depth(args[2]);
      end;
      if ofWindow.exists then;
      screenwidth = ofGetWidth();
      screenheight = ofGetHeight();
      end;
    end;
    ;
    function M.screensize(list);
      screenwidth, screenheight = list[1], list[2];
    end;
    ;
    function M.depth(string);
      if string == "3d" then;
      depth = true;
      else;
      depth = false;
      end;
    end;
    function M.bang();
      ofSetDepthTest(depth);
      ofTranslate(screenwidth*0.5, screenheight*0.5);
      return ofColor(255, 255, 255);
    end;
    

    [ofelia.movie]:

    ofelia d -c17 videoplayer-$0;
    local canvas = ofCanvas(this);
    local args = canvas:getArgs();
    local videoplayer = ofVideoPlayer();
    local filename, start, loop = args[1], args[2], args[3];
    local loaded = 0;
    ;
    function M.new();
      ofWindow.addListener("setup", this);
      if args[1] == nil then print("No file found");
      else M.open(filename);
      end;
      if args[2] == 1 then M.play();
      end;
      if args[3] == nil then loop = 0;
      end;
    end;
    ;
    function M.free();
      ofWindow.removeListener("setup", this);
    end;
    ;
    function M.setup();
      M.open(filename);
    end;
    ;
    function M.open(string);
      if ofWindow.exists then;
        videoplayer:close();
        videoplayer:load(string);
        if (videoplayer:isLoaded()) then;
        print("loaded " .. string);
        videoplayer:update();
        end;
      end;
    end;
    function M.url(string);
      if ofWindow.exists then;
        videoplayer:close();
        videoplayer:load(string);
        if (videoplayer:isLoaded()) then;
          print("loaded " .. string);
          videoplayer:update();
        end;
      end;
    end;
    function M.play() videoplayer:play() end;
    function M.stop() videoplayer:stop() end;
    function M.pause() videoplayer:setPaused(true) end;
    function M.speed(float) videoplayer:setSpeed(float) end;
    function M.frame(float) videoplayer:setFrame(float) end;
    function M.volume(float) videoplayer:setVolume(float) end;
    function M.loop(float);
      if float == 0 then videoplayer:setLoopState(OF_LOOP_NONE);
      elseif float == 1 then videoplayer:setLoopState(OF_LOOP_NORMAL);
      elseif float == 2 then videoplayer:setLoopState(OF_LOOP_PALINDROME);
      end;
    end;
    function M.get()
      return ofTable (videoplayer, videoplayer:isLoaded(), videoplayer:isPlaying(), videoplayer:getCurrentFrame(), videoplayer:getTotalNumFrames(), videoplayer:getWidth(), videoplayer:getHeight());
    end;
    ;
    function M.pointer(p);
      videoplayer:update();
      videoplayer:bind();
      return videoplayer;
    end;
    function M.bang();
      videoplayer:update();
      videoplayer:bind();
      return videoplayer;
    end;
    

    Inside [ofelia.movie] there's this patch:

    [ofelia d movie_script] <- this is the ofelia object that loads the script above
    |
    [t a a]
    |    |
    |    [outlet]
    |
    [ofelia d videoplayer_unbind;] <- this is one object
    [function M.pointer(p);      ]
    [p:unbind;                   ]
    [end;                        ]
    

    and this is [ofelia.cube]:

    ofelia d $0-box;
    local c = ofCanvas(this);
    local args = c:getArgs();
    local width, height, depth, resw, resh, resd, drawmode, strokeweight = args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8];
    local position, orientation, scale = ofVec3f(0, 0, 0), ofVec3f(0, 0, 0), ofVec3f(1, 1, 1);
    ;
    function M.new();
      ofWindow.addListener("setup", this);
      if args[1] == nil then width = 100 end;
      if args[2] == nil then height = 100 end;
      if args[3] == nil then depth = 100 end;
      if args[4] == nil then resw = 5 end;
      if args[5] == nil then resh = 5 end;
      if args[6] == nil then resd = 5 end;
      if args[7] == nil then drawmode = "fill" end;
      if args[8] == nil then strokeweight = 1 end;
      M.setup();
    end;
    ;
    function M.free();
      ofWindow.removeListener("setup", this)
    end;
    ;
    function M.setup();
      box$0 = ofBoxPrimitive();
    end;
    ;
    function M.resw(float) resw = float end;
    function M.resh(float) resh = float end;
    function M.resd(float) resd = float end;
    function M.width(float) width = float end;
    function M.height(float) height = float end;
    function M.depth(float) depth = float end;
    function M.draw(string) drawmode = string end;
    function M.stroke(float) strokeweight = float end;
    function M.position(list) position = ofVec3f(list[1], list[2], list[3]) end;
    function M.orientation(list) orientation = ofVec3f(list[1], list[2], list[3]) end;
    function M.scale(list) scale = ofVec3f(list[1], list[2], list[3]) end;
    ;
    function M.pointer(p);
      ofSetLineWidth(strokeweight);
      box$0:setPosition (position:vec3());
      box$0:setOrientation (orientation:vec3());
      box$0:setScale (scale:vec3());
      box$0:set(width, height, depth, math.abs(resw), math.abs(resh), math.abs(resd));
      if drawmode == "fill" then box$0:drawFaces() end;
      if drawmode == "point" then box$0:drawVertices() end;
      if drawmode == "line" then box$0:drawWireframe() end;
      return p;
    end;
    function M.bang();
      ofSetLineWidth(strokeweight);
      box$0:setPosition (position:vec3());
      box$0:setOrientation (orientation:vec3());
      box$0:setScale (scale:vec3());
      box$0:set(width, height, depth, math.abs(resw), math.abs(resh), math.abs(resd));
      if drawmode == "fill" then box$0:drawFaces() end;
      if drawmode == "point" then box$0:drawVertices() end;
      if drawmode == "line" then box$0:drawWireframe() end;
      return anything;
    end;
    

    This is a bit too much information but I think it's necessary if anyone can help. There's probably stuff I'm ignorant of. @cuinjune any hints?

    posted in pixel# read more
  • alexandros

    right inlet of [symbol].

    posted in technical issues read more
  • alexandros

    @ricky TBH, I don't know. Perhaps you can skip the sleep part and just type the pd launching command right after "reboot". Your Pi is being shut down and powered up again every day or something like this? It sounds strange as to why this is happening, and even though Linux is my OS, I'm no guru by any means. Perhaps the Pd list is the place to find the answer to this.

    posted in technical issues read more

Internal error.

Oops! Looks like something went wrong!