FANDOM


Bus networkEdit

This is implementation of network, where all computers are connected to the same redstone wires. No crossing, no other machinery - just good old redstone dust.

Specs you may be interested with:

  • computerid is int in range 1-254 (0 is for answering pull requests, 255 is brodcast) - yep, you can connect 254 computers together ;P
  • max data package size is 255
  • have anti-collision system
  • no error-correction, i need more Bps for that to be usable
  • uses 3 redstone wires - one for clock and two for data
  • theoretical fastest safe speed: 1,92 Bytes per second

PermissionsEdit

You have my blessing to redistribute and modify this code, as long as you will leave a note about me.


AuthorEdit

D0han

You can find me on IRC: #computercraft @ irc.esper.net

Feedback is welcome

Demo worldEdit

This is demo world, so everyone can check how it works etc.

Only one mod, computercraft, with its default ID (137).

http://d0han.tiberium.net.pl/bus%20network%20world.rar

Backup link: http://www.mediafire.com/?umwaxcbmwgcbxgz

CodeEdit

Main libraryEdit

File magistrala.lua:

--[[
You are free to redistribute and modify this code, as long as you will leave a note about me.

Redstone bus networking library by D0han (can be found on irc: #computercraft @ irc.esper.net)
Specs:
computerid is int in range 1-254 (0 is for answering pull requests, 255 is brodcast) - yep, you can connect 254 computers together ;P
max data package size is 255
have anti-collision system
no error-correction, i need more Bps for that to be usable

you need 3 redstone wires - one for clock and two for data
--]]



waittime = 0.06 -- fastest safe speed (for me), theoretically gives 1,92 Bytes per second
running = true
Dec2BinTable = {}
b = {}

------------borrowed code------------------------
for n=1,8 do
  table.insert(b, 0)
end
for n=0,255 do
    table.insert(Dec2BinTable, 0)
    Dec2BinTable[n] = b[1] .. b[2] .. b[3] .. b[4] .. b[5] .. b[6] .. b[7] .. b[8]
    b[8] = b[8] + 1
    for n2=1,7 do
        if b[9-n2] == 2 then
            b[9-n2] = 0
            b[8-n2] = b[8-n2] + 1
        end
    end
end
------------end of borrowed code------------------
   
function getByte()
    counter = 0
    buffer = ""
    timerrunning = false
   
    while counter < 4 do
        event, param = os.pullEvent()
        if event == "char" and param == exitkey then
            break
        elseif event == "redstone" then
            if redstone.getInput(clockside) then
                if counter == 0 then
                    os.startTimer(10*waittime)
                    timerrunning = true
                end
                bit1 = redstone.getInput(dataside1)
                bit2 = redstone.getInput(dataside2)
                if bit1 then
                    buffer = buffer .. "1"
                else
                    buffer = buffer .. "0"
                end
                if bit2 then
                    buffer = buffer .. "1"
                else
                    buffer = buffer .. "0"
                end
                counter = counter+1
            end
        elseif event =="timer" and timerrunning then
            break
        end
    end
    if counter == 4 then
        --print('get '..buffer)
        return tonumber(buffer, 2)
        --return Bin2Dec(buffer)
    else
        return false
    end
end

function sendDbit(dbit)
    -- dbit = double bit
    if dbit[1] == "1" then
        redstone.setOutput(dataside1, true)
    else
        redstone.setOutput(dataside1, false)
    end
    if dbit[2] == "1" then
        redstone.setOutput(dataside2, true)
    else
        redstone.setOutput(dataside2, false)
    end
    redstone.setOutput(clockside, true)
    sleep(waittime)
    redstone.setOutput(dataside1, false)
    redstone.setOutput(dataside2, false)
    redstone.setOutput(clockside, false)
    sleep(waittime)
end

function sendByte(byte)
    bits = Dec2BinTable[byte]
    --print('send '..bits)
    dbits = {}
    for i=1, #bits, 2 do
        table.insert(dbits, { string.sub(bits, i,i), string.sub(bits, i+1,i+1)})
    end
    for index, dbit in ipairs(dbits) do
        sendDbit(dbit)
    end
end

function checkClear()
    os.startTimer(6*waittime)
    event = os.pullEvent()
    if event == "redstone" and redstone.getInput(clockside) then
        return false
    elseif event =="timer" then
        return true
    end
end

function readPacket(len)

    retries = 0
   
    if not len then
        len = getByte()
    end
    packetbody = {}
    for i=1, len do
        table.insert(packetbody, getByte())
    end
    stopbyte = getByte()
    sleep(6*waittime)
    if stopbyte and stopbyte == 0x51 then
        sendByte(0x51)
        return packetbody
    else
        sendByte(0x52)
        return false
    end
end

function send(addr, body)
    while not checkClear() do
        --print('waiting')
        sleep(6*waittime)
    end
    sendByte(0x50)
    sendByte(0x61)
    sendByte(addr)
    sendByte(#body)
    for i=1,#body do
        letter = string.byte(string.sub(body, i,i))
        sendByte(letter)
    end
    sendByte(0x51)
    status = getByte()
    if status == 0x51 then
        return true
    else
        return false
    end
end

function pull(addr, cellnr)
    sendByte(0x50)
    sendByte(0x60)
    sendByte(addr)
    sendByte(string.byte(cellnr))
    sendByte(0x51)
   
    lastpackets = {0x00, 0x00}
    startpackets = {
        ["trans"] = {0x50, 0x61}
        }
       
    status = getByte()
    if status == 0x51 then
        while true do
            newbyte = getByte()
            if newbyte then
                table.remove(lastpackets, 1)
                table.insert(lastpackets, newbyte)
                for index, val in pairs(startpackets) do
                    if (lastpackets[1] == val[1]) and (lastpackets[2] == val[2]) then
                        operation = newbyte
                        newbyte = getByte()
                        if newbyte == 0x00 then
                            if operation == 0x61 then
                                --print('Incoming answer')
                                body = readPacket()
                                return body[1]
                            end
                        end
                    end
                end
            else
                break
            end
        end
    else
        return false
    end
   
end


--[[
while running do
    print("Listening..")
    newbyte = getByte()
    if newbyte then
        if newbyte == 0x50 then
            newbyte = getByte()
            if newbyte == 0x61 then
                newbyte = getByte()
                print('Transmission to '..newbyte)
                if newbyte == computerid or newbyte == 0xff then
                    print('Incoming transmission')
                    body = readPacket()
                    for index, val in ipairs(body) do
                        write(string.char(val))
                    end
                    print("")
                end
            end
        end
    else
        running = false
        break
    end
end
--]]

Sample of usageEdit

File doorserv:

--[[
Redstone bus networking library by D0han - example of usage
Check 'magistrala.lua' file for more information
--]]
-----------------------------------------CONFIG----------------------------------------------
clockside = "back"
dataside1 = "front"
dataside2 = "right"
exitkey = "q"
computerid = 1
---------------------------------------------------------------------------------------------

shell.run('magistrala.lua')
print("My id: "..computerid)
print("Break key: "..exitkey)
print("")

doorstatus = false

lastpackets = {0x00, 0x00}
startpackets = {
    ['trans'] = {0x50, 0x61},
    ['req'] = {0x50, 0x60}
    }

while running do
    newbyte = getByte()
    if newbyte then
        table.remove(lastpackets, 1)
        table.insert(lastpackets, newbyte)
        for index, val in pairs(startpackets) do
            if (lastpackets[1] == val[1]) and (lastpackets[2] == val[2]) then
                operation = newbyte
                newbyte = getByte()
                if newbyte == computerid or newbyte == 0xff then
                    if operation == 0x61 then
                        print('Incoming transmission')
                        body = readPacket()
                        if body[1] == 0x01 then
                            print('Toggling door')
                            doorstatus = not doorstatus
                            redstone.setOutput("left", doorstatus)
                        else
                            if body[1] == 0x00 then
                                table.remove(body, 1)
                            end
                            for index, val in ipairs(body) do
                                write(string.char(val))
                            end
                            print("")
                        end
                    elseif operation == 0x60 then
                        print('Incoming data request')
                        body = readPacket(1)
                        if body[1] == 0x02 then
                            if doorstatus then
                                print('Reporting that door are opened')
                                send(0x00, string.char(0x01))
                            else
                                print('Reporting that door are closed')
                                send(0x00, string.char(0x02))
                            end
                        end
                    end
                end
            end
        end
    else
        running = false
        break
    end
end


File menu:

--[[
Redstone bus networking library by D0han - example of usage
Check 'magistrala.lua' file for more information
--]]
-----------------------------------------CONFIG----------------------------------------------
clockside = "back"
dataside1 = "front"
dataside2 = "right"
exitkey = "q"
computerid = 2
---------------------------------------------------------------------------------------------

shell.run('magistrala.lua')
print("My id: "..computerid)
print("Break key: "..exitkey)
print("")


while running do
    write("\nMenu:\n1 - Send text message to other computer\n2 - Open/close remote door\n3 - Check status of remote door\n"..exitkey.." - exit program\nYour choice: ")
    param = io.read()
    print("")
    if param == exitkey then
        running = false
        break
    elseif param == '1' then
        message = 
        addr = 
        write('Receiver computer id: ')
        addr = io.read()
        if addr == exitkey then
            running = false
            break
        end
        write('Your message: ')
        message = io.read()
        send(tonumber(addr), string.char(0x00) .. message)
    elseif param == '2' then
        send(2, string.char(0x01))
        print('Remote door toggled')
    elseif param == '3' then
        status = pull(2, string.char(0x02))
        if status == 0x01 then
            print('Remote door are open')
        elseif status == 0x02 then
            print('Remote door are closed')
        else
            print('Error, got '.. tostring(status))
        end
    end
end

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.