Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
|
The IoT Pivot project is about an Intelligent Agriculture System that can be used in Large Irrigation Applications on Center and Linear Pivot Irrigation Systems.
I decided to make this because I live on a farm that irrigates over 1500 acres of land. This land is spread out throughout the valley and grows crops of alfalfa, grass, barley, corn, and more. Much time is consumed travelling to each location just to see that the Pivot is on and running as it should. This product can help us to tell if the Pivot is on without having to drive the many miles and allow us to manage our time more efficiently. It also enables us to check the pivot status multiple times per day with a simple check on our phone.
The design works to have a the Forward or Reverse signal on a Digital Input on the mbed controller which is then published when an update request is received.
When there is no signal on the forward or reverse signal the pivot is off.
In the mobile app when the refresh button is pressed, the pivot status is updated once the pivot is moving either forward or reverse.
Just hook up the signal wires on the FWD 3 and REV 4 signals and ready to go!
Thanks for looking!
public class MainActivity extends AppCompatActivity {
TextView powerText, directionText;
Button refresh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.setSubscribeKey("mykey");
pnConfiguration.setPublishKey("mykey");
pnConfiguration.setUuid("MobilePhone");
final PubNub pubnub = new PubNub(pnConfiguration);
powerText = (TextView) findViewById(R.id.power);
directionText = (TextView) findViewById(R.id.direction);
refresh = (Button) findViewById(R.id.refreshBtn);
refresh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pubnub.publish()
.message(Arrays.asList("PUB"))
.channel("IoTPivot")
.shouldStore(true)
.usePOST(true)
.async(new PNCallback<PNPublishResult>() {
@Override
public void onResponse(PNPublishResult result, PNStatus status) {
if (status.isError()) {
// something bad happened.
System.out.println("error happened while publishing: " + status.toString());
} else {
System.out.println("publish worked! timetoken: " + result.getTimetoken());
}
}
});
}
}
);
pubnub.addListener(new SubscribeCallback() {
@Override
public void status(PubNub pubnub, PNStatus status) {
if (status.getCategory() == PNStatusCategory.PNUnexpectedDisconnectCategory) {
// This event happens when radio / connectivity is lost
}
else if (status.getCategory() == PNStatusCategory.PNConnectedCategory) {
// Connect event. You can do stuff like publish, and know you'll get it.
// Or just use the connected event to confirm you are subscribed for
// UI / internal notifications, etc
if (status.getCategory() == PNStatusCategory.PNConnectedCategory){
pubnub.publish().channel("IoTPivot").message("hello!!").async(new PNCallback<PNPublishResult>() {
@Override
public void onResponse(PNPublishResult result, PNStatus status) {
// Check whether request successfully completed or not.
if (!status.isError()) {
// Message successfully published to specified channel.
}
// Request processing failed.
else {
// Handle message publish error. Check 'category' property to find out possible issue
// because of which request did fail.
//
// Request can be resent using: [status retry];
}
}
});
}
}
else if (status.getCategory() == PNStatusCategory.PNReconnectedCategory) {
// Happens as part of our regular operation. This event happens when
// radio / connectivity is lost, then regained.
}
else if (status.getCategory() == PNStatusCategory.PNDecryptionErrorCategory) {
// Handle messsage decryption error. Probably client configured to
// encrypt messages and on live data feed it received plain text.
}
}
@Override
public void message(PubNub pubnub, PNMessageResult message) {
// Handle new message stored in message.message
if (message.getChannel() != null) {
// Message has been received on channel group stored in
// message.getChannel()
}
else {
// Message has been received on channel stored in
// message.getSubscription()
}
/*
log the following items with your favorite logger
- message.getMessage()
- message.getSubscription()
- message.getTimetoken()
*/
JsonElement result = message.getMessage();
if (result.isJsonObject()) {
JsonObject r = result.getAsJsonObject();
String m = r.get("string").toString();
System.out.println(m);
// Message Format
if(m.contains("PWRON")) {
System.out.println("IoT Pivot is ON");
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
setPowerText("ON");
}
});
}
else if (m.contains("PWROFF")) {
System.out.println("IoT Pivot is OFF");
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
setPowerText("OFF");
setDirectionText("OFF");
}
});
}
if(m.contains("DIRFWD")) {
System.out.println("IoT Pivot is FWD");
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
setDirectionText("FORWARD");
}
});
}
else if (m.contains("DIRRVRS")) {
System.out.println("IoT Pivot is RVRS");
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
setDirectionText("REVERSE");
}
});
}
}
else {
if(message.toString().contains("PWRON")) {
System.out.println("IoT Pivot is ON");
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
setPowerText("ON");
}
});
}
else if (message.toString().contains("PWROFF")) {
System.out.println("IoT Pivot is OFF");
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
setPowerText("OFF");
}
});
}
if(message.toString().contains("DIRFWD")) {
System.out.println("IoT Pivot is FWD");
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
setDirectionText("FORWARD");
}
});
}
else if (message.toString().contains("DIRRVRS")) {
System.out.println("IoT Pivot is RVRS");
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
setDirectionText("REVERSE");
}
});
}
}
}
@Override
public void presence(PubNub pubnub, PNPresenceEventResult presence) {
}
});
pubnub.subscribe().channels(Arrays.asList("IoTPivot")).execute();
}
public void setPowerText(String powerText) {
this.powerText.setText(powerText);
}
public void setDirectionText(String directionText) {
this.directionText.setText(directionText);
}
}
#include "mbed.h"
#include "WNCInterface.h"
#include <string>
#include "pubnub_sync.h"
#include "srand_from_pubnub_time.h"
#define CRLF "\r\n"
WNCInterface eth;
MODSERIAL pc(USBTX,USBRX,256,256);
// Monitoring GPIO
DigitalIn fwdSig(PTC16); // input on the forward signal
DigitalIn rvrsSig(PTC17); // input on the reverse signal
int publish = 1;
static void generate_uuid(pubnub_t *pbp)
{
char const *uuid_default = "zeka-peka-iz-jendeka";
struct Pubnub_UUID uuid;
static struct Pubnub_UUID_String str_uuid;
pubnub_set_uuid(pbp, "P1");
}
int main()
{
pc.baud(115200);
pc.printf(CRLF CRLF "Pubnub Test starting..." CRLF);
pc.printf("init() returned 0x%04X" CRLF, eth.init(NULL,&pc));
eth.connect();
pc.printf("IP Address: %s" CRLF, eth.getIPAddress());
eth.doDebug(1);
pubnub_t *pbp = pubnub_alloc();
pubnub_init(pbp, "mykey", "mykey"); // insert your pubnub key here
if (fwdSig.is_connected()) {
pc.printf("fwdSig is connected and initialized. \n\r");
}
if (rvrsSig.is_connected()) {
pc.printf("rvrsSig is connected and initialized. \n\r");
}
while (true) {
const char *json = "{\"string\": \"empty\"}";
if(fwdSig.read() && !rvrsSig.read()){
json = "{\"string\": \"PWRONDIRFWD\"}";
}
else if (!fwdSig.read() && rvrsSig.read()){
json = "{\"string\": \"PWRONDIRRVRS\"}";
}
else if (!fwdSig.read() && !rvrsSig.read()){
json = "{\"string\": \"PWROFF\"}";
}
if (publish == 0) {
publish = 1;
pubnub_res rslt = pubnub_publish(pbp, "IoTPivot", json);
//pubnub_publi
if (rslt != PNR_STARTED) {
pc.printf("Failed to start publishing, rslt=%d"CRLF, rslt);
}
else {
rslt = pubnub_await(pbp);
if (rslt != PNR_OK) {
pc.printf("Failed to finished publishing, rslt=%d"CRLF, rslt);
}
else {
pc.printf("Published! Response from Pubnub: %s"CRLF, pubnub_last_publish_result(pbp));
}
}
}
pubnub_res sub_rslt = pubnub_subscribe(pbp, "IoTPivot", 0);
if (sub_rslt != PNR_STARTED) {
pc.printf("Failed to start subscribing, sub_rslt=%d"CRLF, sub_rslt);
}
else {
sub_rslt = pubnub_await(pbp);
if (sub_rslt != PNR_OK) {
pc.printf("Failed to finished subscribing, sub_rslt=%d"CRLF, sub_rslt);
}
else {
pc.printf("Subscribed! Received messages follow: %s"CRLF);
while (char const *msg = pubnub_get(pbp)) {
pc.printf("subscribe got: %s"CRLF, msg);
if (strstr(msg, "PUB")) {
pc.printf("Asked to publish");
publish = 0;
}
}
}
}
wait_ms(1000);
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="iotpivot.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="IoT Pivot Status"
android:id="@+id/title"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="56dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="direction"
android:id="@+id/direction"
android:layout_alignTop="@+id/refreshBtn"
android:layout_toRightOf="@+id/title"
android:layout_toEndOf="@+id/title"
android:layout_marginLeft="43dp"
android:layout_marginStart="43dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="power"
android:id="@+id/power"
android:layout_above="@+id/direction"
android:layout_alignLeft="@+id/direction"
android:layout_alignStart="@+id/direction" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh"
android:id="@+id/refreshBtn"
android:layout_below="@+id/title"
android:layout_alignLeft="@+id/title"
android:layout_alignStart="@+id/title"
android:layout_marginTop="32dp" />
</RelativeLayout>
Comments