Nova's Redstone Circuits

Discussion in 'ComputerCraft Programming' started by gknova61, Jan 8, 2013.

?

What's the next circuit you want to see?

  1. State Cell

    28.6%
  2. Some type of gate

    0 vote(s)
    0.0%
  3. Randomizer

    28.6%
  4. Multiplexer

    0 vote(s)
    0.0%
  5. Counter

    28.6%
  6. Other (please specify below)

    14.3%
  1. gknova61

    gknova61 Farbes Lover

    Joined:
    Mar 17, 2012
    Messages:
    1,238
    Likes Received:
    350
    UPDATE 3/6/13: Original timer program has been updated! Also added a new timer that works with bundled cable, and can have multiple timers working simultaneously for the different colors!

    As my first post up in this shiny new section, a thread for redstone circuits in vanilla and Redpower done in ComputerCraft, which can hopefully cut down on some client lag some of us have been getting from the lighting updates from ComputerCraft's counterparts and offer a bit more customization along the way.

    (screenshots pending)

    The Timer (currently v0.2 - Adds a blue screen!):
    Instructions:
    When you run the program for the first time, you'll need to specify parameters. First, run "<program-name> usage" and a screen should pop-up like this:
    (screenshot pending)

    Run with "usage" as an arguement (enter 'timer usage' into computer) to get extended documentation on how to use the program

    Here is the basic jist of every parameter:

    Interval - The amount of seconds to wait in between timer pulses

    Side - The side for the timer to output redstone on

    inputSide - This is the side that if the timer get's a redstone signal on, it'll halt until it's turned off

    pulseTime (optional, defaults to .2sec)- This is just how long to keep the pulse on when the timer ticks
    Code:
    os.pullEvent = os.pullEventRaw
     
    if os.getComputerLabel() ~= nil then
    label = "ID #"..os.computerID().." (\""..os.getComputerLabel().."\")"
    else
    label = "ID #"..os.computerID()
    end
     
    local w,h = term.getSize()
    local function cPrint(text)
    w,h = term.getSize()
    local x,y = term.getCursorPos()
    term.setCursorPos(math.ceil(w-text:len())/2,y)
    print(text)
    end
     
    tArgs = {...}
     
    local function main()
    loaded = false
    dir = ""
    file = ""
    path = ""
    internal = {}
    local function create()
    local file = fs.open(path,"a")
    file.close()
    end
     
    local function load(directory,fileName)
    dir = directory
    file = fileName
    if dir ~= nil then
    path = dir.."/"..file
    fs.makeDir(dir)
    create(path)
    local file = fs.open(path, "r")
    repeat
    line = file.readLine()
    if(line ~= nil) then
    local asWords = line:gsub(":","")
    local parts = {}
    for word in asWords:gmatch("%w+") do table.insert(parts,word) end
    internal[parts[1]] = parts[2]
    end
    until line == nil
    loaded = true
    file.close()
    else
    path = file
    create(path)
    local file = fs.open(path, "r")
    repeat
    line = file.readLine()
    if(line ~= nil) then
    local asWords = line:gsub(":","")
    local parts = {}
    for word in asWords:gmatch("%w+") do table.insert(parts,word) end
    internal[parts[1]] = parts[2]
    end
    until line == nil
    loaded = true
    file.close()
    end
    end
     
    local function writeVal(key,value)
    if(loaded == false) then
    return false
    else
    local toWrite = value
    if(value == true) then toWrite = "true"
    elseif(value == false) then toWrite = "false" end
    internal[key] = toWrite
    return true
    end
    end
     
    local function readVal(key)
    if(loaded == false) then
    return nil
    end
    toReturn = internal[key]
    if(toReturn == "true") then return true
    elseif(toReturn == "false") then return false
    else return internal[key] end
    end
     
    local function save()
    if(loaded == true) then
    local file = fs.open(path,"w")
    for i,v in pairs(internal) do
    file.writeLine(i.." = "..v)
    end
    file.close()
    internal = {}
    loaded = false
    return true
    else
    return false
    end
    end
     
    local function isEmpty()
    if(loaded == false) then
    return nil
    end
    if(fs.getSize(path) == 0)then
    return true
    else return false end
    end
     
    local function printUsage()
    print("Usage:")
    print(shell.getRunningProgram().." <interval> <side> <Input Side> (Pulse Time)")
    print("Interval is how long the timer will wait before pulsing")
    print("Pulse Time is the sPulseSide to pulse redstone on")
    print("Input Side is the side that the timer will stop ifit receives a redstone signal")
    print("Pulse time is how long to keep the pulse on when the timer ticks")
    print()
    print("Parameters:")
    print("[] = Required")
    print("() = Optional")
    return true
    end
     
    if not fs.isDir(".timer") then
    fs.makeDir(".timer")
    end
     
    if #tArgs < 3 and not fs.exists(".timer/config") then
    printUsage()
    return false
    elseif #tArgs < 3 and fs.exists(".timer/config") then
    noArgsGood = true
    end
     
    if tArgs[1] == "usage" then
    printUsage()
    return false
    end
     
    load(".timer","config")
    if noArgsGood == nil then
    nInterval,sPulseSide,sSideInput,nPulseTime = tonumber(tArgs[1]),tArgs[2],tArgs[3],tonumber(tArgs[4])
    writeVal("nInterval",tostring(nInterval))
    writeVal("sPulseSide",sPulseSide)
    writeVal("sSideInput",sSideInput)
    writeVal("nPulseTime",tostring(nPulseTime))
    elseif noArgsGood then
    nInterval,sPulseSide,sSideInput,nPulseTime = tonumber(readVal("nInterval")),readVal("sPulseSide"),readVal("sSideInput"),tonumber(readVal("nPulseTime"))
    end
    save()
     
    if nPulseTime == nil then
    nPulseTime = 0.2
    end
     
    while true do
    os.startTimer(nInterval)
    local event = {os.pullEvent()}
    if event[1] == "redstone" and rs.getInput(sSideInput) then
    while true do
    local event = {os.pullEvent("redstone")}
    if event[1] == "redstone" and not rs.getInput(sSideInput) then
    break
    end
    end
    elseif event[1] == "timer" then
    rs.setOutput(sPulseSide,true)
    sleep(nPulseTime)
    rs.setOutput(sPulseSide,false)
    end
    end
    end
     
    local ok, err = pcall(main)
    if not ok then
    if term.isColor() then
    term.setBackgroundColor(colors.blue)
    end
    term.setTextColor(1)
    term.clear()
    term.setCursorPos(1,2)
    cPrint("A fatal error has occured at "..label)
    term.setCursorPos(1,math.ceil(h/2))
    cPrint(err)
    print()
    term.setCursorPos(1,h-3)
    cPrint("Take a screenshot and report this to gknova61")
    term.setCursorPos(1,h-1)
    local nTime = 10
    repeat
    term.setCursorPos(1,h-1)
    term.clearLine()
    cPrint("Restarting in "..nTime.." seconds")
    nTime = nTime-1
    sleep(1)
    until nTime == 0
    os.reboot()
    end
    

    Future Plans:
    -Make more circuits :p
    -Somehow 'modularize' these circuits so users can essentially create their own circuits on one computer
    -Make this more user-friendly (Perhaps a GUI if the computer is advanced?)
    -Add auto-updating if HTTP is enabled (Likely to be in the next update)
    -Add model numbers and branding (will be optional to put on - likely to be in the next update)
    Credits: Config API by ben657 and Hooks & Timers by my_hat_stinks
     
  2. Pathaleon

    Pathaleon Forum & Server Administrator
    Staff Member

    Joined:
    Jul 3, 2012
    Messages:
    1,014
    Likes Received:
    670
    Make a multi timer software with bundled cable. eg multiple timers one pc!
     
  3. gknova61

    gknova61 Farbes Lover

    Joined:
    Mar 17, 2012
    Messages:
    1,238
    Likes Received:
    350
    Will work on it hopefully in the next few days ;)

    Edit: Woo, that was quick! The only thing holding this program's release is Pastebin being down :(
     
  4. LeiserGeist

    LeiserGeist Gamer, Software Developer

    Joined:
    Oct 26, 2012
    Messages:
    479
    Likes Received:
    116
    Multiplexer would be cool