Project updated to beta 6.0.1 (released on December 20th, 2021)
In this Meadow project we'll learn how to build a clock that shows you the time and date on a LED Matrix using a public web service API, and room temperature with an LM35 analog temperature sensor. We will see how easy is to connect your Meadow board to your home wireless network with its onboard WIFI capabilities, and we'll use Meadow.Foundation to drive the peripherals and MicroGraphics to draw text and lines on the display.
Meadow.Foundation a platform for quickly and easily building connected things using.NET on Meadow. Created by Wilderness Labs, it's completely open source and maintained by the Wilderness Labs community.
If you're new working with Meadow, I suggest you go to the Getting Started w/ Meadow by Controlling the Onboard RGB LED project to properly set up your development environment.
Step 1 - Assemble the circuitWire your project like this:
Create a new Meadow Application project in Visual Studio 2019 for Windows or macOS and name it WifiClock.
Step 3 - Add the required NuGet packagesFor this project, search and install the following NuGet packages:
Step 4 - Add Configuration Files (if missing)In your project, create and add the following configuration files:
meadow.config.yaml
# Acceptable values for true: true, 1, yes
# Acceptable values for false: false, 0, no
#===============================================================================
# main device config
Device:
# Name of the device on the network.
Name: WifiClock
#===============================================================================
# Network configuration.
Network:
# Automatically attempt to get the time at startup?
GetNetworkTimeAtStartup: true
# Time synchronization period in seconds.
NtpRefreshPeriod: 600
# Name of the NTP servers.
NtpServers:
- time.google.com
- time1.google.com
- time2.google.com
- time3.google.com
# IP addresses of the DNS servers.
DnsServers:
- 142.103.1.1
- 65.39.139.53
This configuration file is used for when Meadow is powered on, it looks for these values here and takes action depending on what's defined, like GetNetworkTimeAtStartup set to true, to get the UTC date and time using the NtpServers and DnsServers listed.
IMPORTANT: Right click on the config file and go to the Properties, and make sure the Build Action is set to Content and Copy to Output Directory to Copy Always or Copy If Newer.
Secrets.cs
We'll use this class to store the WIFI credentials.
public class Secrets
{
/// <summary>
/// Name of the WiFi network to use.
/// </summary>
public const string WIFI_NAME = "[SSID]";
/// <summary>
/// Password for the WiFi network names in WIFI_NAME.
/// </summary>
public const string WIFI_PASSWORD = "[PASSWORD]";
}
MeadowApp.cs
In our main class, copy the following code:
public class MeadowApp : App<F7Micro, MeadowApp>
{
PushButton pushButton;
Max7219 display;
GraphicsLibrary graphics;
AnalogTemperature analogTemperature;
bool showDate;
public MeadowApp()
{
Initialize();
Start();
}
void Initialize()
{
RgbPwmLed onboardLed = new RgbPwmLed(device: Device,
redPwmPin: Device.Pins.OnboardLedRed,
greenPwmPin: Device.Pins.OnboardLedGreen,
bluePwmPin: Device.Pins.OnboardLedBlue,
3.3f, 3.3f, 3.3f,
Meadow.Peripherals.Leds.IRgbLed.CommonType.CommonAnode);
onboardLed.StartPulse(Color.Red);
display = new Max7219(
device: Device,
spiBus: Device.CreateSpiBus(),
csPin: Device.Pins.D01,
deviceCount: 4,
maxMode: Max7219.Max7219Type.Display);
graphics = new GraphicsLibrary(display);
graphics.CurrentFont = new Font4x8();
graphics.Rotation = GraphicsLibrary.RotationType._180Degrees;
graphics.Clear();
graphics.DrawText(0, 1, "WI");
graphics.DrawText(0, 9, "FI");
graphics.DrawText(0, 17, "TI");
graphics.DrawText(0, 25, "ME");
graphics.Show();
pushButton = new PushButton(Device, Device.Pins.D04, ResistorMode.PullUp);
pushButton.Clicked += PushButtonClicked;
analogTemperature = new AnalogTemperature(
device: Device,
analogPin: Device.Pins.A00,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
Device.InitWiFiAdapter().Wait();
onboardLed.StartPulse(Color.Blue);
var result = Device.WiFiAdapter.Connect(
Secrets.WIFI_NAME, Secrets.WIFI_PASSWORD);
if (result.ConnectionStatus != ConnectionStatus.Success)
{
onboardLed.StartPulse(Color.Magenta);
throw new Exception($"Cannot connect to network: {result.ConnectionStatus}");
}
onboardLed.StartPulse(Color.Green);
}
void PushButtonClicked(object sender, EventArgs e)
{
showDate = true;
Thread.Sleep(5000);
showDate = false;
}
async Task Start()
{
var dateTime = await WeatherService.GetTimeAsync();
Device.SetClock(new DateTime(
year: dateTime.Year,
month: dateTime.Month,
day: dateTime.Day,
hour: dateTime.Hour,
minute: dateTime.Minute,
second: dateTime.Second));
while (true)
{
DateTime clock = DateTime.Now;
graphics.Clear();
graphics.DrawText(0, 1, $"{clock:hh}");
graphics.DrawText(0, 9, $"{clock:mm}");
graphics.DrawText(0, 17, $"{clock:ss}");
graphics.DrawText(0, 25, $"{clock:tt}");
if (showDate)
{
graphics.Clear();
graphics.DrawText(0, 1, $"{clock:dd}");
graphics.DrawText(0, 9, $"{clock:MM}");
graphics.DrawText(0, 17, $"{clock:yy}");
for (int i = 0; i < 8; i++)
{
graphics.DrawPixel(i, 24);
}
float temperature = analogTemperature.Read().Result.Temperature.Value;
graphics.DrawText(0, 26, $"{(int) temperature}");
}
graphics.Show();
Thread.Sleep(1000);
}
}
}
We can split the logic here in two main methods:
Initialize()
Here
we're initializing all the peripherals connected to Meadow, and the WIFI connection to your network. You'll see the onboard LED turning red when the app starts, and it will turn blue after initializing the AnalogTemperature sensor, the push button and the MAX7219 dot matrix (which will greet you with a WIFI TIME in the display). When the LED is pulsing blue, it will now initialize the WIFI module and it will turn green once its successfully connected to your network.
We also have a Clicked
event handler (PushButtonClicked
) for the push button, which sets a boolean field (showDate
) true
for five seconds, and assigning it back to false
.
Start()
The
first thing this method will do is call WeatherService's GetTimeAsync()
method to get the information from the public web API, and once it returns the DateTime value, we can set the Time and Date to Meadow's onboard RTC module by doing Device.SetClock()
so in the infinite while look we can get the Time every second and show it on the display.
Inside the While loop notice that we use the showDate
boolean field to show today's date and room temperature in the bottom, separated by a horizonal line. This will only be drawn for five seconds whenever we push the button.
Click the Run button in Visual Studio. It should look like to the following GIF:
This project is only the tip of the iceberg in terms of the extensive exciting things you can do with Meadow.Foundation.
- It comes with a huge peripheral driver library with drivers for the most common sensors and peripherals.
- The peripheral drivers encapsulate the core logic and expose a simple, clean, modern API.
- This project is backed by a growing community that is constantly working on building cool connected things and are always excited to help new-comers and discuss new projects.
Comments