Most people play card games for entertainment value but they also provide several benefits to our emotional and mental health. Card games keep our minds active, boost concentrating, and offer a social outlet all of which are key factors in a happy and healthy life. It is one of the most popular indoor activities.
Most of the card games like Rummy and Poker needs a dealer. The dealer takes all of the cards in the pack, arranges them so that they are in a uniform stack. The dealer may deal the cards one at a time, or in groups or packets, as indicated by the rules. In some games, all cards are dealt, while in other versions, some cards are left undistributed and are placed – or stacked – in the center of the table. The automatic card dealers are introduced in the market purposefully for carrying out that huge task. So why can't we go for an audio-based one?
So we are introducing the solution, ABCD
ABCD is Alexa based card dealers that are completely powered by Alexa and Lego Mindstorms ev3 kit. It is a perfect audio compatible card dealer. You can deal with the cards by simply speaking to ABCD and it also provides the voice responses, just as those of the human dealers. Ideal for using it during tournaments and playing professionally even at home.
Let's watch the working before getting into the making.
Building the bricksWe are building the card dealer with the Lego Mindstorms ev3 31313 kit. For the sake of simplicity in building, the card dealer is made by assembling several blocks with several steps. We are making each block separately, and at last, we will combine it together. The interesting fact is that it needs only One Lego Mindstorms ev3 kit for building the whole.
You can check the catalog of Lego Mindstorms ev3 31313 here for getting knowledge about the bricks available in this kit.
Note:Build instructions for the each block are attached in github repo as PDF
Then here comes the separate block making.
1. Depot making
This is the block where we store the cards, and also distributed from here.
Here I am using the Bridge Cards for making out the play. Bridge cards are one of two standard sizes of a playing card – the other being Poker cards. Bridge cards measure 3.5 inches tall and 2.25 inches wide (88.9mm x 56mm).This is slightly narrower than Poker cards which measure 3.5 inches by 2.5 inches (88.9mm x63.5mm).
You can adjust the depot size according to the card type, whether it is poker or bridge cards by simply adding up or removing this brick(4142135) as shown below.
The medium motor is attached to the Depot for distributing cards. Just go through the instruction for this block, attached below. Then the first block is over. Then we can go to the second one.
2. Rotating Platform
The Depot that made above is attached to the Rotating platform so the cards can easily be distributed for the players by the rotating platform through the concerned angles. This is also attached to the Large Motor for rotations.
The below image shows the connectors in which Depot is connecting to.
There is also an axle in the rotating platform for the connection with the Large Motor as shown below.
So the second block is over. Let's get into the next one.
3. RotorBlock
Here in this block, we are attaching the Medium Motor with the Intelligent Ev3 brick. This section forms the brain of the card dealer.
When the platform rotates, we need to balance the Large Motor side, otherwise, it will lead to improper rotations. So we are using the rubber wheels purposefully.
This section doesn't move(Stationary part). Then we can head over to the next section.
4.Medium MotorSection
The EV3 Medium Servo Motor is great for lower-load, higher speed applications and when faster response times and a smaller profile are needed, that's why I choose the medium motor here, also we all know that it is less weighing than the large motor. So it reduces the whole weight of the rotating platform to a great extent which will probably lead to the smooth movement of the platform.
This motor is used for distributing the cards for the players. It is connected with the depot.
The Wedge-Belt-Wheel and the tire is the key part of this section, because it is pushing out the card from the depot. We used three here, for faster movements.
I think, in the instruction for making this block. You can't find the rubber tyre with the wheel(because the part 602841 is missing in lego designer studio). So don't forget to attach the tyre with the wheel.
5. Slottedweight Block
This block is connected with the depot.
These are used for the giving weight for the cards, placed in the depot. So the underneath card will be easily swiped out from the depot. When a card is swiped out the weight will automatically come down by the gravity.
The hinging mechanism is paving the way for weight slots to move up and down.
Note: Build instructions for the each block are attached in the github repo as PDFAssembly
Here we are assembling the whole blocks that we have built before. It is actually pretty simple.
First, we can connect the Slotted Weight Block with the Depot. Now it constitutes the Depot.
Then we can connect the Depot with the Rotating Platform.
As you can see the Depot isn't aligned straight with the platform(front section is raised to certain angles). There is some logic behind it. By this configuration, it will distribute only one card at a time. Suppose when we are aligning it straight, it will lead to improper distribution of cards.
Then this platform is attached with the Rotator Block(Large Motor Section)
Here comes the final assembly of the medium motor to the above one.
After all the assembly we could get something like this.
The brick building is over. Here I provided images of assembly, because it is very easy to visualize the situations than the normal instructions. Then we can head over to the wiring of ev3 brick to motors.
Note: The build instruction for the blocks are made both in Lego Digital Designer(LDD) and Bricklink Studio.Wiring
Here actual hardware comprises one medium and large motor and also one ev3 brick. The motors should be connected to any of the ports(A, B, C, D) of the ev3 brick for proper working. Connections are made using the cables which are coming in the kit. As you can see in the kit, the same type of cable is available in three different lengths. We are using
1 X 50 cm cable for medium motor
1 X 25 cm cable for large motor
As you can see the medium motor needs lengthy cables to make out at least a 360-degree rotation. That's why I am using the 50 cm cable for that, otherwise, it halts the movement of the platform. For the Large motor, the 25 cm cable is enough.
The connections are
Port A ----> Medium Motor
Port B -----> Large Motor
The wiring has just finished. Let's get into the software part.
SoftwareSettingUp
The instructions for the below steps are given here (setup)
- Install ev3dev for programming your EV3 Brick
- Install Visual Studio Code for editing code
- Install Alexa Gadgets Python Software on your EV3 Brick
I am not repeating the same steps, instead, I can give you the tips.
When you downloaded the ev3 software, you need to flash it to an SD card. I prefer Class 10 SD cards. For the flashing, we use Etcher or Rufus. For booting up you need to put the SD card into the brick. For putting up SD card bare hands are enough but when you are removing I will prefer Tweezers.
So for the ev3 brick, it needs 6 x AA battery having each one 1.5V. I prefer rechargeable batteries having high energy storage capacity(high mah). Higher the mAh rating of a battery, the longer the battery will last. mAH
is a unit of electric charge. For this project, I am using Panasonic Eneloop rechargeable battery having capacity up to 2550 mah.
Then boot up the ev3 brick by a long press on the center button. After boot up, it will be like this.
If you have no idea about the basics of ev3 brick just go here. Then you must connect the ev3 brick to the internet by sharing your computer internet connectivity. For connecting to the computer there are different methods, here I am using the USB cable which is coming with the kit itself. I think it is an easy method. Have a look here for connecting to the Internet via USB. These are the other ways of networking.
NOTE: I am having Windows with me, so the networking for Mac OSX and Ubuntu will be different.
After getting the internet connection, let's shoot up the Visual Studio Code editor for programming the brick. Visual Studio Code is just a source-code editor developed by Microsoft. Why we are using it is?
It will recommend extensions that make it easy to connect to and program your EV3 Brick. As you can see when you download the cardealer.zip file and open with the visual studio code editor it will automatically recommend the extensions. So install the ev3dev-browser extension shown up. If you have Python installed on your computer, you can install that extension too. (Don't install it if you don't have Python already installed.) (Python is the language used here for the programming).Just go through the setup, everything is described there, perfectly. At last, the workspace will be available in your ev3 brick.
Registering EV3 brick as Alexa Gadget
In order for your EV3 Brick to work with Alexa and your Echo device as an Alexa Gadget, you will need to register your gadget in the Alexa Developer Console. Registering your gadget ties your unique gadget to your account, and is required in order for your creation to work properly with Alexa. An Alexa Gadget is an Alexa connected accessory that interacts with compatible Amazon Echo devices over Bluetooth.
Here it describes how it is done. Amazon ID and Alexa Gadget Secret should be noted up, because it uniquely identifies our gadget. The following figure shows how a gadget interacts with an Echo device, and where the Alexa Gadgets interfaces fit in.
If you need more knowledge about this, just have a look here. This documentation provides what exactly is
- Detail description of how gadget interact with Alexa
- Echo devices that support gadgets
- Things to be in mind, when creating Alexa gadgets.
When you've successfully registered your Alexa Gadget. Let's prepare the ev3 brick
Preparingev3 brick
Your EV3 Brick will be connecting to your Echo device using Bluetooth, which you'll need to enable on your Brick in order for the sample code to work correctly: For more instructions look here.
Note: If Bluetooth is “Not Available”, POWER OFF your Brick, power it back on, and try turning on Bluetooth again. If not yet available try re-flashing you OS.
Once Bluetooth is enabled, you’re ready to work with some code!
At this point, you can switch over to the Visual Code Workspace you created during the setup instructions. The Explorer panel should display the mission folders that are on your computer.
Registration and Settings
Within the carddealer
folder, you will see an INI file and a Python file. Open up the carddealer.ini
file, which includes the following configuration details:
[GadgetSettings]
amazonId = YOUR_GADGET_AMAZON_ID
alexaGadgetSecret = YOUR_GADGET_SECRET
[GadgetCapabilities]
Alexa.Gadget.StateListener = 1.0 - wakeword
The INI (or initialization) file defines parameters for how your EV3 Brick should work as a gadget:
Gadget Settings: Specifies the Amazon ID and Alexa Gadget Secret that you received when you created your gadget in the Amazon Developer Console. It authenticates your EV3 Brick and allows it to connect to your Echo device and Alexa.
Howto set upecho dot?
Tip: Before setup, download or update the Alexa app in your mobile device's app store.
- Open the Alexa app
- Go to the settings menu
- Select Add Device.
- Select Amazon Echo, and then Echo Dot.
- Plug in your device.
- Follow the instructions to set up your device.
Pairing Echo with Brick
In order to work with the Alexa, the EV3 Brick needs to establish a Bluetooth connection with the Echo device.
The Echo device and the gadget discover each other over Classic Bluetooth as follows:
- The user puts the gadget into pairing mode. This procedure depends on the gadget. For example, a button gadget might use a long press. If your gadget has a touchscreen, a user could enable pairing through an option on the screen.
- The user puts the Echo device into pairing mode. For Echo devices without a screen, a user can put an Echo device into pairing mode by using the Amazon Alexa app. In the Alexa app, the user goes to Settings, selects the Echo device, and then selects Pair Alexa Gadget under Connected Devices. If the Echo device has a screen, the user follows on-screen instructions to initiate pairing. (screenshots are given for reference)
Just click on the "pair a new device", please be patient it will take some time. Here I am using the echo dot 3rd generation.
Create your Alexa skillLet’s walk through the steps of creating your Skill:
1. Sign in to developer.amazon.com.
2. In the top header, hover over Alexa, and click on Alexa Skills Kit.
3. In the upper-right of the screen, click on Create Skill.
4. Enter a Skill Name, maybe “CARDDEALERS”. The name you give your Skill will also be the way you open the Skill. For example, “Alexa, open carddealers”,
5. Select your default language. Make sure the language select matches the language used on your Echo device.
6. Select Custom for the “Choose a model to add to your skill” option.
7. Select Alexa-Hosted for the “Choose a method to host your skill's backend resources” option.
Note: At the time of writing, the Python option for Alexa-Hosted skills was not available, but this method will work. We will work to add a guide for Python-based skills in the future. In the meantime, you can reference the Color Cycler Alexa skill for the Raspberry Pi sample to get started.
8. Click Create skill in the upper-right.
9. Once you click Create skill, you will see a modal while your skill is being prepared to be customized.
Enable the Custom Interface Controller
The Custom Interface Controller allows you to send custom commands to your EV3Brick (Custom Directives), and receive events from your EV3 Brick (Custom Events). For this mission, you will need to enable the Custom Interface Controller, so you can use Custom Directives:
1. Click on Interfaces in the left navigation of the Alexa Developer Console.
2. Toggle Custom Interface Controller to ON.
3. Scroll to the top of the page and click Save Interfaces
That’s it! With Custom Interface Controller toggled on, you can write code that sends custom directives to your EV3 Brick and program how you want it to react. Learn more about Custom Interfaces.
Define the Skill Interaction Model
The Skill Interaction Model defines how you can speak to your skill, and what kind of commands it can expect to respond to. The interaction model includes intents, slots, sample utterances that you define, and program against in your skill’s code. Learn more about the Skill Interaction Model.
1. In the Alexa Developer Console, under Interaction Model, click on JSON Editor.
2. In the carddealer
folder, you will see a folder called skill-nodejs
. Within that folder, there is a model.json
file. Copy the interaction model JSON from that file, and paste it into the editor, or drag and drop the JSON file onto the drop zone to upload it.
After pasting the JSON into the Alexa skill JSON Editor, click Save Model, and then Build Model presented at the top of the console interface. It may take some time for the model to build, so be patient. In the meantime, let’s explore the Intents and Slots in the JSON file.
An intent represents an action that fulfills a user's spoken request. Intents can optionally have arguments called slots. For example, in the JSON you will see a SetPlayerIntent
with slots for Player
, which maps to a predefined AMAZON.NUMBER
integer value. The combination of the intent and slots will allow us to write code that reacts to:
“Alexa, tell carddealers to setplayers to 2”
Other intents in the JSON file include GiveIntent
, that accepts a value
slot mapped to AMAZON.NUMBER
, which is an unbounded integer. You will need to perform a range check and bound it from 1 to 52 inclusive, in the skill code. The DistributeIntent
will start the distribution. These intents and slots allow you to write code that reacts to:
“Alexa, tell carddealersto give me a card”
“Alexa, tell carddealersto distribute”
Take a moment to browse through these intents and their slots — key things to note are:
- Intent names (SetPlayerIntent, GiveIntent, DistributeIntent)
- Slot name (Player, Value)
- Slot values ("1", "2", "52")
With your Intents and Slots defined, you’re ready to start implementing the Skill code.
There’s a lot to learn about creating skills, but for the purpose of this mission, we’ll guide you through using the Alexa-Hosted skill option you selected earlier, and share additional resources at the end. With an Alexa-Hosted skill, you can start writing code for your skill directly in the Alexa Developer Console:
1. Click on Code in the top navigation bar of the Alexa Developer Console.
2. In VS Code, open the index.js
file in the carddealer/skill-nodejs/lambda
folder.
3. Copy the code in the index.js
file into the index.js
file in the Alexa Developer Console Code Editor.
4. Copy the contents of the package.json
and util.js
files to the respective files in the Alexa Skill Code Editor.
5. Create a new file by clicking the New File icon in the upper-left of the Code Editor, and fill in the path and file name as /lambda/common.js
6. With the common.js
file created, make sure the file is open, and then copy the code in the common.js
file from the carddealer/skill-nodejs/
folder in VS Code to the common.js
file in the Alexa Skill Code Editor.
Now, let’s take a look at the core elements of the index.js
file. The snippet below contains all of the handlers used by this skill. The last four handlers are lifted from the skill template — no modifications needed.
exports.handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
SetPlayerIntentHandler,
GiveIntentHandler,
DistributeIntentHandler,
Common.HelpIntentHandler,
Common.CancelAndStopIntentHandler,
Common.SessionEndedRequestHandler,
Common.IntentReflectorHandler, // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers
)
.addRequestInterceptors(Common.RequestInterceptor)
.addErrorHandlers(
Common.ErrorHandler,
)
.lambda();
There are also three unique handlers that have been added.
LaunchRequestHandler
This handler is invoked when you launch the skill by saying, “Alexa, open carddealers”. When the skill is launched, the following occurs: The endpointID
of the MindstormsGadget
is obtained using:
let request = handlerInput.requestEnvelope;
let { apiEndpoint, apiAccessToken } = request.context.System;
let apiResponse = await Util.getConnectedEndpoints(apiEndpoint, apiAccessToken);
if ((apiResponse.endpoints || []).length === 0) {
return handlerInput.responseBuilder
.speak("I couldn't find an EV3 Brick connected to this Echo device. Please check to make sure your EV3 Brick is connected, and try again.")
.getResponse();
}
If there is no EV3 Brick connected to the Echo device, the skill replies with a message. Otherwise, the endpointID
is stored as a session attribute. Session attributes allow you to retain data during the skill session:
let endpointId = apiResponse.endpoints[0].endpointId || [];
Util.putSessionAttribute(handlerInput, 'endpointId', endpointId);
Once the endpointID
is stored, the skill continues by welcoming the person speaking to the Echo device:
let out = "Welcome to card dealers, To know about commands use help,"
return handlerInput.responseBuilder
.speak(out)
.reprompt("Awaiting commands")
.getResponse();
SetPlayerIntentHandler
This handler is invoked when you say, “Alexa, tell carddealers to set players to 5”, or similar. When the skill is invoked using this utterance, the following code obtains the player value from the slot and stores that value for reference in a session attribute.
let player = Alexa.getSlotValue(handlerInput.requestEnvelope, 'Player');
player = Math.max(1, Math.min(10, parseInt(player)));
Util.putSessionAttribute(handlerInput, 'player', player);
GiveIntentHandler
This handler is invoked when you say, “Alexa, tell carddealersto give me 2 cards”, or other similar supported utterance. When the skill is invoked using this utterance, the following code gets the values from the Value
slot to construct a command that will be sent to the EV3 Brick to make EV3RSTORM move. If a value is not available for the Value
slot, the command falls back to the default value stored as a session attribute.
const request = handlerInput.requestEnvelope;
const attributesManager = handlerInput.attributesManager;
let endpointId = attributesManager.getSessionAttributes().endpointId || [];
const Value = attributesManager.getSessionAttributes().value;
Once all the parameters are available, a control
custom directive is constructed to send to the MindstormsGadget
. This custom directive is then parsed on the EV3 Brick using code we’ll review later.
let directive = Util.build(endpointId, NAMESPACE, NAME_CONTROL,
{
type: 'give',
value: Value,
});
return handlerInput.responseBuilder
.speak(`Giving you ${Value} cards `)
.addDirective(directive)
.getResponse();
DistributeIntentHandler
This handler is invoked when you say, “Alexa, tell carddealersto distribute”, or other similar supported utterance. A control
custom directive is constructed to send to the MindstormsGadget
. This custom directive is then parsed on the EV3 Brick using code we’ll review later.
const DistributeIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'DistributeIntent';
},
handle:function (handlerInput) {
const request = handlerInput.requestEnvelope;
const attributesManager = handlerInput.attributesManager;
let endpointId = attributesManager.getSessionAttributes().endpointId || [];
const player = attributesManager.getSessionAttributes().player || "3";
let directive = Util.build(endpointId, NAMESPACE, NAME_CONTROL,
{
type: 'distribute',
player:player,
});
return handlerInput.responseBuilder
.speak(`Starting distribution`)
.addDirective(directive)
.getResponse();
}
};
With this skill logic in place, you can test the skill, but you will find that you receive a response indicating that your EV3 Brick has not been detected:
1. Click Deploy in the upper-right of the Alexa Skill Code Editor. Wait for the deployment process to complete.
2. In the top navigation bar of the Alexa Developer Console, click on Test.
3. You can choose to enable the microphone on your computer or not.
4. Switch the testing from Off to Development using the dropdown under the navigation bar.
5. In the panel on the left, you can either type “open carddealers”, or say that utterance when you press the microphone button (you will have opted to enable the microphone on your computer for this to work).
6. You should get a response along the lines of, “I couldn't find an EV3 Brick connected to this Echo device. Please check to make sure your EV3 Brick is connected, and try again”, which you specified in the LaunchRequestHandler
.
Your skill is working! Let’s complete the other side of the experience by reviewing and running the EV3 code to get EV3RSTORM to react to your skill
Now let's move on to build the python code.
Python CodeHandling the Custom Directive from the Alexa skill
From the Alexa Skill, you are sending a custom directive — specifically the custom directive with the Custom.Mindstorms.Gadget
namespace and Control
name. In order for EV3RSTORM to react, you need to define what happens when data is received via the Custom.Mindstorms.Gadget
interface you defined. Within the carddealer
folder, open the carddealer.py
file.
Similar to handling the Alexa wake word and the music tempo directives, handling this directive requires extending the AlexaGadget
class and defining a callback method. Within the MindstormsGadget
class, a callback method is defined using a convention to match the capability you added to the.ini file:
on_custom_namespace_name(self, directive)
This method definition breaks down as:
on_custom
is a prefix indicating that this is a custom callback methodnamespace
is your defined custom interface namespacename
is your defined custom interface namedirective
is the custom directive with the corresponding namespace and name
The formatting of the method definition is derived from the dot syntax of the Custom Interface, coupled with the custom interface name, and dots are converted to dashes, as well as lowercase characters. So, for the custom interface that maps directly to what was specified in the.ini file, the method looks like:
on_custom_mindstorms_gadget_control(self, directive)
You can learn more about custom directives in the documentation, but the MindstormsGadget
class for this mission looks like this:
from agt import AlexaGadget
class MindstormsGadget(AlexaGadget):
def __init__(self):
super().__init__()
def on_custom_mindstorms_gadget_control(self, directive):
"""
Handles the Custom.Mindstorms.Gadget control directive.
:param directive: the custom directive with the matching namespace and name
"""
payload = json.loads(directive.payload.decode("utf-8"))
print("Control payload: {}".format(payload))
control_type = payload["type"]
if control_type == "distribute":
self._distribute(int(payload["player"]))
if control_type == "give":
print(int(payload["value"]))
self._give(int(payload["value"]))
if __name__ == '__main__':
MindstormsGadget().main()
This receives the custom directive, which you can then parse and use the parameters to make EV3RSTORM respond in a variety of ways.
The Python code above sets up the motors connected to the EV3 Brick and tells EV3RSTORM how to move when it receives commands from the Alexa skill, including:
- The cards will be distributed by the combined rotations of large and medium motors in the specified direction
- The cards will be given away by the rotations of the medium motor only
The detailed documentation is given in the GitHub Readme.
Note: Make sure your echo device is powered on and have proper internet connection before running the code.
The ABCD is ready, just shuffle the cards and place them in the depot and enjoy the game!
Comments