Jump to content




Peripheral Basics


9 replies to this topic

#1 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 02 September 2013 - 08:45 PM

This is a tutorial in the Ask a Pro Renewal Project series.

Pre-requisite tutorials:
Computer Basics I
Computer Basics III

Leads onto:
— Peripheral Intermediate
— Modem Intermediate
— Monitor basics

Preface

In this tutorial, we will learn about interacting with peripherals in ComputerCraft via the Peripheral API. We will be covering the following peripheral functions: isPresent, getType, getMethods, call, and wrap. It is highly recommended that you follow along with the tutorial while going though it.

In ComputerCraft we are provided with several peripherals that we can use to our amusement. The image below shows what we can interact with like a peripheral as of ComputerCraft version 1.56

Posted Image


In order to interact with these peripherals we are provided with the Peripheral API.

Note: There are 100s other peripherals added by mods, to use these usage of the Peripheral API is no different, however in this tutorial we will only be dealing with the vanilla ComputerCraft peripherals.

Over the course of this tutorial we will be using a Computer with four (4) Advanced Monitors attached to the computer on the right. We will also later be attaching a Disk Drive anywhere on the computer. However for now your setup should look like this.

Posted Image
We will also be using the Lua Prompt to execute commands while learning how a function works, and the edit program to create some small programs to run once we have learnt how the function works. After you have setup the computer and monitors, and opened Lua prompt we can begin.

Lets begin...

Well Before We Begin

Before we cover the functions in the peripheral API just some information to be aware of while we are going through this tutorial.

A peripheral can be located in one (1) of seven (7) places:
  • Top
  • Bottom
  • Left
  • Right
  • Front
  • Back
  • Network
We will only be using the first six (6) in this tutorial as there is an entire tutorial later on in this series that covers number seven (7).

When using the side a peripheral is located inside our code we enter the side that the peripheral appears on our screen when looking at the front of the computer.

Now lets move on to the Peripheral API...

isPresent

When we are making programs that will make use of peripherals, we can never be sure of where peripherals are attached to the computer, or even where the peripherals are located. For this purpose we are provided with the `isPresent` function. The function `isPresent` will return true or false depending on if something we can interact with via the peripheral API is located on that side. In the Lua prompt type in peripheral.isPresent("left") and press enter. You should have something like this

Posted Image

You will notice that it has printed false as there is no peripheral located on the left side of the computer.

Now if you type in peripheral.isPresent("right") you should have it print true (seen below), as that is the side the monitors are located.

Posted Image

Now I will take a pause in the tutorial to allow you to have a play with the `isPresent` function with various peripherals on various sides.

Knowing now how this function works we can write a small program in the edit program to print the sides that a computer is located. Exit Lua Prompt and create a new program called `present`, add the following code, and save the file.

local sides = { "top", "bottom", "left", "right",
"front", "back" }

for i = 1, #sides do
  if peripheral.isPresent(sides[i]) then
	print("Something is on the "..sides[i])
  end
end

As you can see in this block of code, we first define a table containing all the valid names of directions that the peripheral can appear. Next we then iterate through this table, checking if there is a peripheral on each of those sides with isPresent, printing a message if we find anything.

You should now have the following

Posted Image

Now run the file `present` and observe the results. It should say "Something is on the right", like so...

Posted Image

Congratulations, you have taken the first step towards making a program that automatically detects peripherals.

getType

Now that we know how we can locate peripherals we want to know what the peripheral is. For this task we have been provided it the function `getType`. This function will return us a string that is the peripherals type. These are the returned types of the peripherals shown in the first image of this tutorial;
  • Computer or Advanced Computer is "computer"
  • Any Turtle or any Advanced Turtle is "turtle"
  • Wired Modem or Wireless Modem is "modem"
  • Monitor or Advanced Monitor is "monitor"
  • Disk Drive is "drive"
  • Printer is "printer"
Now go back into the Lua Prompt. If we now type peripheral.getType("right") and press enter, it should say "monitor" as we have an Advanced Monitor on the right, if we type peripheral.getType("left") and press enter, nothing will print, as there is no peripheral on that side.

Posted Image

Now I will take a pause in the tutorial to allow you to have a play with the `getType` function with various peripherals on various sides.

Knowing how this function works now, we can expand the program from before and have it print what is on each side of the computer. Exit the Lua prompt and make a copy of the `present` program, and call it `type`. Now open `type` in edit and we shall begin.

Lets edit the program so that it will print the type of the peripheral as well as the side it is located. Scroll down to line six (6) and change it to say the following

print("A "..peripheral.getType(sides[i]).." is on the "..sides[i])

This time as we loop through the side names, and check that they are there, with isPresent, when we come to printing out the message instead of printing the static message "Something is on that side", we build a string that contains the name of the peripheral on that side, as well as the side that is on.

Save and run the program and you should now have an output like the following

Posted Image

I will now take another short pause in the tutorial to allow you time to have a play around with the program, placing peripherals on other sides and seeing the output of the program.

Now lets make another program called `monitors`. This program will locate any monitors and print what side they are on. But only monitors.

local sides = { "top", "bottom", "left", "right", "front", "back" }

print("Finding monitors...")
for i = 1, #sides do
  if peripheral.isPresent(sides[i]) then
	if peripheral.getType(sides[i]) == "monitor" then
	  print("Found: "..sides[i])
	end
  end
end

It can be seen in the code above, that most of this is similar to the other loops we have been creating. Where it differs it that after we check if the peripheral is present we then proceed to check it's type as well, and compare that against what we expect: "monitor". If it then passes both of these tests we output the side the monitor was found on.

Before we run this program add a Disk Drive on any other side of the computer in order to test the program.

As seen below when we run this program you will notice that it outputs that it has located a monitor on the right side, but does not mention the disk drive, unlike the previous two (2) programs would have.

Posted Image


This loop that we just created is a very powerful tool in making very advanced programs that are able to locate the peripherals they require and when not found can inform the user they are required. As an example, this is a function that I use commonly when working with peripherals. You should be able to understand how this is working

local function findPeripheral( periphType )
  for _, side in pairs( rs.getSides() ) do
	if peripheral.isPresent(side) and peripheral.getType(side) == periphType then
	  return side
	end
  end

  error("Cannot find "..periphType.." attached to this computer", 0)
end

The above function allows you to supply what peripheral you're after and if it can find it, it will return which side it is located on (only the first it encounters, if there are 4 monitors, it will return the side that the first is found). For example findPeripheral("monitor") would search for a monitor, and from the setup we have would return "right". Other than specifying the type of peripheral you are after, it works no differently than the other loop we created just before.

getMethods

Note: For those who don't know why it is called `getMethods` instead of `getFunctions`, this is because the list that it returns is of the Java side methods, and not Lua functions. Until you learn more about programming just think of these as the same. As such I will be using both interchangeably in the rest of this tutorial

Now that we know how we can find peripherals attached to a computer, you are probably wondering how we can actually do anything useful with these peripherals. Well all the peripherals that we are provided supply us with some functions that we can use in order to interact with the peripheral. When we call the `peripheral.getMethods` function we will get back a table of all the functions we can interact with the peripheral through. As such the purpose of `peripheral.getMethods()` is not one that we would really use in released programs, however it is very useful for us as developers to be able to know what functions we can call on our peripherals to interact with them.

Lets now make a program that makes use of this function, and tells us what we can do with the a peripheral from the supplied side. Lets create a new file called `methods` and begin...
The `getMethods` function requires on argument, a side. So lets write call that and save it into a variable.

local side = ...
local methods = peripheral.getMethods(side)

In the above code we first get an argument from runtime, we then assume that it will be a valid side (this is bad, always validate) and then use that to get the methods of the peripheral.

Now in the methods variable we have a table of functions that can be called on the monitor, so lets see what they are by iterating this new table that we have and printing it's contents
local side = ...
local methods = peripheral.getMethods(side)

for i = 1, #methods do
  print( i.." = "..methods[i] )
end

Save, exit and run the program with the argument "right". You should have the following output.

Posted Image
We now know all the things we can do with the monitor, looks a lot like the normal terminal doesn't it!

I will take a short pause in the tutorial again to allow you to have a play with the program we just created on various peripheral to see what can be done with them.


call

Now this is where we start using the knowledge of what functions we can interact with the peripheral. The `call` function allows us to interact with the peripheral by invoking the method on the peripheral. This function is an open ended function and allows us to give it an unlimited amount of arguments to it (also known as vararg function) as different peripheral calls require different things to operate, for example the `setBackgroundColor` on the monitor requires one (1) argument, the color, where as the function to set the cursor's position requires two (2), the x and y coordinates.

The `call` function does have a requirement of two arguments however, the side of the peripheral and the method to call on that peripheral. Any additional arguments supplied to it will be passed along to the method being called on the peripheral.

As a test of how to use this function, lets use that Disk Drive that we placed on the computer a while ago. We will detect if there is a disk inside of it, setting its label, and then eject it. Place a floppy disk inside and lets begin.

First lets, run the `methods` program with the side of the Disk Drive so that we can see what we are able to call on it. From that list you should see the two methods we will be using; "isDiskPresent", "setDiskLabel", and "ejectDisk". Open the Lua Prompt and type peripheral.call("right", "isDiskPresent") and press enter, that should have output true.

Posted Image
Now type peripheral.call("right", "setDiskLabel", "tutorial") and press enter. That should have been accepted. Now lets eject the disk and check. Type peripheral.call("right", "ejectDisk") and press enter, the disk should be ejected onto the ground in front of the Disk Drive, pick up the drive and hover over it, it should have the label "tutorial".

Posted Image

Note: You can actually remove the disk from the drive via the GUI, just like when you placed it in, we are just doing it via code to get used to peripheral calls.

wrap

Now while invoking the methods on the peripheral with the `call` function is fine, it can make our programs become very verbose and having to type `peripheral.call` and then specify the side of the peripheral each time can become quite annoying and tiresome. As such the peripheral API provides us with the last function we will be covering in this tutorial, `wrap`. The `wrap` function accepts one (1) argument, the side of the peripheral, and returns us a table containing all the methods we can call on the peripheral.

Lets use the same example as above and interact with the Disk Drive again. We will detect if there is a floppy disk present, label it, and then eject it from the drive. Place a different floppy disk in the drive and lets begin.

Still in the Lua Prompt lets wrap the peripheral into a variable, type drive = peripheral.wrap("left") and press enter, that should have been accepted. To test that our `drive` variable now has a table you can type drive and press enter, it should output something like the following

Note: The numbers and letters will vary, however the reason as to why is outside the scope of this tutorial.
Posted Image
Now that we have wrapped the drive into a variable we can call the functions on this just like we do any API. Now type into the prompt drive.isDiskPresent() and press enter, it should output true just as before

Posted Image
Now lets label and eject the disk. Type drive.setDiskLabel("wrapped") drive.ejectDisk() and press enter, the disk should be labelled and ejected from the Disk Drive. Pick up the disk and check the label to confirm.

Posted Image
Congratulations, you have now successfully wrapped and interacted with a peripheral.

Conclusion

We have now come to an end to this tutorial. In this tutorial we learnt how to check for peripherals and detect what kind of peripheral they are, we then inspected the peripheral and checked how we could interact with it, which we then did two (2) ways; direct calling on the peripheral and through wrapping the peripheral into a variable.

Thank you for joining me in this tutorial, thanks for reading, enjoy playing with the peripherals, happy coding, and see you next time!

Edited by Lyqyd, 06 November 2014 - 05:03 AM.


#2 Zudo

  • Members
  • 800 posts
  • LocationUK

Posted 03 September 2013 - 02:04 AM

Nice tutorial
Nice skin
:)

#3 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 03 September 2013 - 03:23 AM

View PostZudoHackz, on 03 September 2013 - 02:04 AM, said:

Nice tutorial
Nice skin
:)
Thanks and thanks :) the back of the suit has "BIT" written on it.

#4 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 03 September 2013 - 12:49 PM

The first code example needs a plain English description of the code, perhaps something like, "As you can see, in this block of code, we first create a table containing each of the valid side names. Next, we iterate through this table and check each of those side names with peripheral.isPresent, and print a message if we find anything." The other example programs could use similar treatment. We don't want to over-explain it, but we also don't want to blindly assume they'll know what's going on straight away. A quick description should be enough for most people to figure out which parts of the code do which parts of the description. You won't have to fully re-describe the common parts each time, so the second description could start out, "This time, as we loop through the side names, ..."

Under call, "vararg function" should probably link to the PIL.

I'm not sure what "NB:" stands for, but it seems like it could be replaced with "Note:"?

Looks very good other than that! Definitely seems to me to be at the right level for Peripheral Basics. Thanks for the effort.

#5 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 03 September 2013 - 11:58 PM

View PostLyqyd, on 03 September 2013 - 12:49 PM, said:

The first code example needs a plain English description of the code, perhaps something like, "As you can see, in this block of code, we first create a table containing each of the valid side names. Next, we iterate through this table and check each of those side names with peripheral.isPresent, and print a message if we find anything." The other example programs could use similar treatment. We don't want to over-explain it, but we also don't want to blindly assume they'll know what's going on straight away. A quick description should be enough for most people to figure out which parts of the code do which parts of the description. You won't have to fully re-describe the common parts each time, so the second description could start out, "This time, as we loop through the side names, ..."

Under call, "vararg function" should probably link to the PIL.
Ok can do, I'll make that change now. EDIT: done

View PostLyqyd, on 03 September 2013 - 12:49 PM, said:

I'm not sure what "NB:" stands for, but it seems like it could be replaced with "Note:"?
define:NB but sure, I'll replace with note.It's a habit I've got into from writing reports at uni, we have to write them correctly, so have to use things like NB, et al and a bunch of other things. EDIT: done

View PostLyqyd, on 03 September 2013 - 12:49 PM, said:

Looks very good other than that! Definitely seems to me to be at the right level for Peripheral Basics. Thanks for the effort.
Cool cool, thanks for the feedback :)

Edited by theoriginalbit, 04 September 2013 - 02:19 AM.


#6 blockly

  • Members
  • 41 posts
  • LocationSan Francisco, California, USA

Posted 18 October 2013 - 12:51 PM

Great tutorial! This has been a huge help. I wish I'd read it sooner.

#7 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 20 October 2013 - 12:38 AM

View Postblockly, on 18 October 2013 - 12:51 PM, said:

Great tutorial! This has been a huge help. I wish I'd read it sooner.
Thank you. Its good to get such positive feedback! :)

#8 Mtbred01

  • Members
  • 3 posts

Posted 06 July 2014 - 09:44 AM

Much like your turtle basics, this was super easy to understand. One small recommendation, when you discuss the setup used for the tutorial, possibly consider adding that we also will use two floppy disks. That way there isn't a need to run off and craft a floppy disk or two while working through the tutorial. Looking forward to your next tutorial!

Edited by Mtbred01, 06 July 2014 - 10:30 AM.


#9 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 06 November 2014 - 05:03 AM

I went ahead and added the link for Computer Basics III. ;)

#10 up4round2

  • New Members
  • 1 posts

Posted 20 November 2014 - 02:43 AM

Thanks I really appreciate this tutorial. My dad was an electrical and mechanical engineer as well as a electrical repair technician. I built a (at the time) cutting edge pc at 8 and have really loved it. I never really did much gaming though... a friend turned me to Minecraft a couple months ago and Computercraft is exactly what I've been looking for as a simple way to channel my recreation. Much awesomeness to everybody on staff. XD





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users