Skip to content

Commit 3f72455

Browse files
author
dave
committed
More examples prior to releasing properly hello example still to be tested.
1 parent d4195c5 commit 3f72455

File tree

4 files changed

+283
-0
lines changed

4 files changed

+283
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//
2+
// Created by David Cherry on 25/06/2020.
3+
//
4+
5+
#include <IoLogging.h>
6+
#include "NTPTimeEvent.h"
7+
8+
void acquireNtpTimeThreadProc(NTPTimeEvent *ntpTime) {
9+
ntpTime->acquireNtpOnThread();
10+
}
11+
12+
NTPTimeEvent::NTPTimeEvent(NetworkInterface *nwInterface, const char *serverName, int port)
13+
: timeServer(serverName), timePort(port), interface(nwInterface),
14+
ntpThread(), _presentValue(0) {
15+
ntpThread.start(callback(acquireNtpTimeThreadProc, this));
16+
}
17+
18+
void NTPTimeEvent::acquireNtpOnThread() {
19+
int retriesLeft = 20;
20+
while(--retriesLeft > 0) {
21+
// wait a second before trying to avoid a tight loop.
22+
ThisThread::sleep_for((20 - retriesLeft) * 1000);
23+
24+
serdebugF2("Starting ntp loop retries = ", retriesLeft);
25+
26+
SocketAddress serverAddr;
27+
if (interface->gethostbyname(timeServer, &serverAddr) < 0) {
28+
continue;
29+
}
30+
serverAddr.set_port(timePort);
31+
32+
serdebugF("Found NTP host");
33+
34+
int32_t ntpRx[12] = {0};
35+
char ntpTx[48] = {0};
36+
ntpTx[0] = 0x1b;
37+
38+
UDPSocket socket;
39+
socket.open(interface);
40+
socket.set_blocking(true);
41+
socket.set_timeout(10);
42+
43+
int sendCount = 0;
44+
nsapi_size_or_error_t sendRet;
45+
while((sendRet = socket.sendto(serverAddr, ntpTx, sizeof(ntpTx))) <= 0) {
46+
if(sendRet != NSAPI_ERROR_WOULD_BLOCK || ++sendCount > 20) break;
47+
ThisThread::sleep_for(500);
48+
}
49+
50+
serdebugF("Sent NTP message");
51+
52+
SocketAddress sourceAddr;
53+
sendCount = 0;
54+
while(sendRet > 0 && ++sendCount < 20) {
55+
int n = socket.recvfrom(&sourceAddr, ntpRx, sizeof(ntpRx));
56+
57+
if (n > 10) {
58+
uint32_t tmNowRaw = ntpRx[10];
59+
uint32_t ret = (tmNowRaw & 0xffU) << 24U;
60+
ret |= (tmNowRaw & 0xff00U) << 8U;
61+
ret |= (tmNowRaw & 0xff0000UL) >> 8U;
62+
ret |= (tmNowRaw & 0xff000000UL) >> 24U;
63+
_presentValue = ret - EPOCH_CONVERT_OFFSET;
64+
markTriggeredAndNotify();
65+
serdebugF2("Time was set to ", (unsigned long) _presentValue);
66+
return;
67+
}
68+
}
69+
// finally close the socket
70+
socket.close();
71+
}
72+
}
73+
74+
uint32_t NTPTimeEvent::timeOfNextCheck() {
75+
return secondsToMicros(1);
76+
}

examples/mbedClock/NTPTimeEvent.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
3+
#ifndef TCMENUEXAMPLE_NTPTIMEEVENT_H
4+
#define TCMENUEXAMPLE_NTPTIMEEVENT_H
5+
6+
#include <mbed.h>
7+
#include <ctime>
8+
#include <EthernetInterface.h>
9+
#include <TaskManagerIO.h>
10+
11+
/**
12+
* Provides an easy way to get the time from an NTP server as an event, the exec method is not implemented on this
13+
* so that you can implement it how you see fit. This class works by starting a thread to acquire the time from an
14+
* NTP server, and when the time is obtained, it triggers the event.
15+
*/
16+
class NTPTimeEvent : public BaseEvent {
17+
public:
18+
/**
19+
* Create the event for a given interface, server and port.
20+
* @param interface the interface to use
21+
* @param timeServer the NTP server name
22+
* @param timePort the port to connect on
23+
*/
24+
NTPTimeEvent(NetworkInterface* interface, const char* timeServer, int timePort);
25+
26+
uint32_t timeOfNextCheck() override;
27+
28+
private:
29+
const time_t EPOCH_CONVERT_OFFSET = (time_t)2208988800UL;
30+
const char* const timeServer;
31+
const int volatile timePort;
32+
NetworkInterface* const interface;
33+
Thread ntpThread;
34+
35+
void acquireNtpOnThread();
36+
friend void acquireNtpTimeThreadProc(NTPTimeEvent *ntpTime);
37+
protected:
38+
volatile time_t _presentValue;
39+
};
40+
41+
42+
#endif //TCMENUEXAMPLE_NTPTIMEEVENT_H

examples/mbedClock/analogClock.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/**
2+
* A more complex example that acquires time from the network using NTP and displays it on the screen
3+
* The NTP class is apache licensed, and can be used directly in your code
4+
*
5+
* MBED 6 RTOS example.
6+
*/
7+
8+
#include <cstdio>
9+
#include "mbed.h"
10+
#include <TaskManager.h>
11+
#include <IoLogging.h>
12+
#include <NetworkInterface.h>
13+
//#include "Adafruit_SSD1306_I2c.h" (for i2c displays)
14+
#include "Adafruit_SSD1306_Spi.h"
15+
#include "NTPTimeEvent.h"
16+
17+
// Host PC Communication channels
18+
BufferedSerial pc(USBTX, USBRX);
19+
MBedLogger LoggingPort(pc);
20+
21+
bool running = true;
22+
23+
//I2C i2c(PF_0,PF_1);
24+
//Adafruit_SSD1306_I2c gfx(i2c, NC, SSD_I2C_ADDRESS, 64, 132, SH_1106);
25+
26+
SPI spi(PB_5, PB_4, PB_3);
27+
Adafruit_SSD1306_Spi gfx(spi, PD_15, PF_12, PF_13, 64, 128, SSD_1306);
28+
29+
// we are going to use NTP, we need to enable the network device to get a reading.
30+
NetworkInterface* defNetwork = NetworkInterface::get_default_instance();
31+
32+
// here we calculate teh centre points of the screen in terms of the clock.
33+
float offsetY = 20.0F + (float(gfx.height() - 20.0F) / 2.0F);
34+
float offsetX = float(gfx.width()) / 2.0F;
35+
float magFactor = (float(gfx.height()) / 2.0F) - 12.0F;
36+
37+
// we need to know the position of the hour hand at each interval, and also the minute / second hand
38+
float degsPerHour = 360.0F / 12.0F;
39+
float degsPerMinute = 360.0F / 60.0F;
40+
#define MATH_PI_FLT 3.141593F
41+
42+
//
43+
// couple of forward declarations
44+
//
45+
void dealWithHand(float degMultiplier, int value, float mag);
46+
void prepareRealtimeClock();
47+
48+
inline float toRadian(float deg) {
49+
if(deg > 360.0F) deg = deg - 360.0F;
50+
return (deg * MATH_PI_FLT) / 180.F;
51+
}
52+
53+
int main()
54+
{
55+
//i2c.frequency(400000);
56+
57+
gfx.begin();
58+
59+
prepareRealtimeClock();
60+
61+
taskManager.scheduleFixedRate(1, [] {
62+
auto timeNow = time(nullptr);
63+
auto tm = gmtime(&timeNow);
64+
65+
gfx.clearDisplay();
66+
67+
for(int i=0; i<12; i++) {
68+
float deg = float(i) * degsPerHour;
69+
float rads = toRadian(deg);
70+
gfx.fillCircle(offsetX + (magFactor * sin(rads)), offsetY + (magFactor * cos(rads)), 2, WHITE);
71+
}
72+
73+
dealWithHand(degsPerHour, 12 - (tm->tm_hour % 12), magFactor * 0.65F);
74+
dealWithHand(degsPerMinute, 60 - tm->tm_min, magFactor * 0.75F);
75+
dealWithHand(degsPerMinute, 60 - tm->tm_sec, magFactor * 0.95F);
76+
77+
char sz[30];
78+
sprintf(sz, "Time: %02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
79+
gfx.setCursor(0,0);
80+
gfx.print(sz);
81+
82+
gfx.display();
83+
}, TIME_SECONDS);
84+
85+
while(running) {
86+
taskManager.runLoop();
87+
}
88+
}
89+
90+
void dealWithHand(float degMultiplier, int value, float mag) {
91+
float deg = (float(value) * degMultiplier);
92+
float rads = toRadian(deg);
93+
94+
float xEnd = offsetX - (mag * sin(rads));
95+
float yEnd = offsetY - (mag * cos(rads));
96+
gfx.drawLine(offsetX, offsetY, xEnd, yEnd, WHITE);
97+
}
98+
99+
class ClockNtpTimeEvent : public NTPTimeEvent {
100+
public:
101+
102+
ClockNtpTimeEvent(NetworkInterface *interface, const char *timeServer, int timePort)
103+
: NTPTimeEvent(interface, timeServer, timePort) {
104+
}
105+
106+
void exec() override {
107+
set_time(_presentValue);
108+
setCompleted(true);
109+
}
110+
};
111+
112+
void prepareRealtimeClock() {
113+
if(defNetwork->connect() != NSAPI_ERROR_IS_CONNECTED) {
114+
taskManager.scheduleOnce(250, prepareRealtimeClock);
115+
return;
116+
}
117+
118+
taskManager.registerEvent(new ClockNtpTimeEvent(defNetwork,"2.pool.ntp.org", 123), true);
119+
}

examples/mbedHello/mbedHello.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* the simplest possible example of using an OLED display with our library
3+
*/
4+
5+
#include <cstdio>
6+
#include "mbed.h"
7+
#include <TaskManager.h>
8+
//#include "Adafruit_SSD1306_I2c.h" (for i2c displays)
9+
#include "Adafruit_SSD1306_Spi.h"
10+
11+
bool running = true;
12+
13+
//I2C i2c(PF_0,PF_1);
14+
//Adafruit_SSD1306_I2c gfx(i2c, NC, SSD_I2C_ADDRESS, 64, 132, SH_1106);
15+
16+
SPI spi(PB_5, PB_4, PB_3);
17+
Adafruit_SSD1306_Spi gfx(spi, PD_15, PF_12, PF_13, 64, 128, SSD_1306);
18+
19+
int main()
20+
{
21+
//i2c.frequency(400000);
22+
23+
gfx.begin();
24+
25+
gfx.clearDisplay();
26+
gfx.setCursor(0, 0);
27+
gfx.setTextColor(WHITE);
28+
gfx.print("Hello mbed");
29+
30+
31+
// actually cause the write to take place.
32+
gfx.display();
33+
34+
taskManager.scheduleFixedRate(1, [] {
35+
gfx.fillRect(0, 20, gfx.width(), 20);
36+
gfx.setCursor(0, 20);
37+
gfx.print(millis());
38+
39+
// actually cause the write to take place.
40+
gfx.display();
41+
}, TIME_SECONDS);
42+
43+
while(running) {
44+
taskManager.runLoop();
45+
}
46+
}

0 commit comments

Comments
 (0)