Internet of Things

Develop Wi-Fi, BLE, MQTT in iOS and iPadOS, Android, and Windows.
Everything could be connected. Everything shall be connected.

Wi-Fi

Wi-Fi is a family of wireless network protocols, based on the IEEE 802.11 family of standards, which are commonly used for local area networking of devices and Internet access, allowing nearby digital devices to exchange data by radio waves.
Wi-Fi uses multiple parts of the IEEE 802 protocol family and is designed to interwork seamlessly with its wired sibling Ethernet. Compatible devices can network through wireless access points to each other as well as to wired devices and the Internet. Wi-Fi most commonly uses the 2.4 gigahertz (120 mm) UHF and 5 gigahertz (60 mm) SHF radio bands; these bands are subdivided into multiple channels. Channels can be shared between networks but only one transmitter can locally transmit on a channel at any moment in time.
The Wireless Ethernet Compatibility Alliance (WECA) is a non-profit organization formed in 1999 to certify interoperability of Wi-Fi (IEEE 802.11b High Rate) products and to promote Wi-Fi as the global wireless LAN standard across all market segments. In October 2002, it was officially renamed the Wi-Fi Alliance. Wi-Fi stands for "wireless fidelity".

Camellia Mini Controller works as an Access Point, configuring a Wireless Local Area Network.
Mobiles or PCs work as Stations which are connecting to this Access Point.
In computer networking, a Wireless Access Point (WAP), or more generally just Access Point (AP), is a networking hardware device that allows other Wi-Fi devices to connect to a wired network. As a standalone device, the AP may have a wired connection to a router, but, in a wireless router, it can also be an integral component of the router itself. An AP is differentiated from a hotspot which is a physical location where Wi-Fi access is available.
Look at your Robots or AIs directly and operate them at home or in the office, even outside.

Camellia Mini Controller works as a Station, connecting to the Internet via another Access Point.
Remote control your Robots or AIs from anywhere in Mobiles or PCs anytime via the Internet or 4G/5G cellular signal.

Here is the typical code of Android, Windows and iOS and iPadOS for mobiles or PCs work as Stations, which will connect to an Access Point:

  • Java is used for Android
  • C# is used for Windows
  • Swift is used for iOS and iPadOS


Station in Android with Java to control Camellia Mini Controller which is an Access Point using socket

1. Varify Wi-Fi Hardware
Code in Activity:
MainActivity activity = (MainActivity) getActivity();
Context mcontext = activity.getApplicationContext();
ConnectivityManager mConnectivityManager = (ConnectivityManager) mcontext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWiFiNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

if( mWiFiNetworkInfo != null && mWiFiNetworkInfo.isConnected() ) {
   WifiManager mWifiManager = (WifiManager) mcontext.getSystemService(Context.WIFI_SERVICE);
   WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
   // ...
}
else{
   // ...
}

2. Set Variables
Code in Activity:
private Socket mSocket = new Socket();
private OutputStream mOutputStream = null;
private InputStream mInputStream = null;
private InetAddress mIPAddress;
public int mDevicePortWiFi;
// Server IP
public String mDeviceAddressWiFi = "192.168.4.1"; 

private byte[] bufWiFi = new byte[64];
Thread for Connect, Send and Receive:
private ConnectSeverThread mConnectThread;
private SendtoSeverThread mSendThread;
private ReceivefromSeverThread mReceiveThread;

3. Connect to An Access Point
Code in Activity:
public void ConnecttoServer(){
      mConnectThread = new ConnectSeverThread();
      mConnectThread.start();
}
Code in Thread:
private class ConnectSeverThread extends Thread {
   public void run() {
      try
      {
         mIPAddress = InetAddress.getByName(mDeviceAddressWiFi);
         mSocket = new Socket(mIPAddress, mDevicePortWiFi);
		 
         // Or Using belowing method to set a time out action
         // mSocket = new Socket();
         // SocketAddress socAddress = new InetSocketAddress(mIPAddress, mDevicePortWiFi);
         // mSocket.connect(socAddress, 5000);
		 
		 runOnUiThread(new Runnable() {
            public void run() {
            }
         });
      }
      catch(IOException e)
      {
         e.printStackTrace();
      }
   }
}

4. Send Messages
Code in Activity:
public void sendDataWiFi(byte[] data) {
   if( mSocket.isClosed() == false ) {
      for( i = 0 ; i < 64 ; i++ ){
         bufWiFi[i] = data[i];
      }
      mSendThread = new SendtoSeverThread();
      mSendThread.start();
   }
}
Code in Thread:
private class SendtoSeverThread extends Thread {
   public void run() {
      if( mSocket.isClosed() == false ) {
         try
         {
            mOutputStream = mSocket.getOutputStream();
            mOutputStream.write(bufWiFi);
         }
         catch(IOException e)
         {
             e.printStackTrace();
         }
      }
   }
}

5. Receive Messages
Code in Activity:
public void receiveDataWiFi( ) {
   if( mSocket.isClosed() == false ) {
      mReceiveThread = new ReceivefromSeverThread();
      mReceiveThread.start();
   }
}
Code in Thread:
private class ReceivefromSeverThread extends Thread {
   public void run() {
      if( mSocket.isClosed() == false ) {
         try
         {
            mInputStream = mSocket.getInputStream();
            // GBK for Chinese
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mInputStream,"GB18030"));
            // UTF-8
            // BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mInputStream,"UTF-8"));  
         }
         catch(UnsupportedEncodingException e)
         {
            e.printStackTrace();
         }
      }
   }
}
Android system identify "\n" as the end sign of each Receiving.

6. Messages among Threads
Code in Activity:
private Handler handler = new Handler() {
   @Override
   public void handleMessage(Message msg) {
      // ...
   }
}
Code in Thread:
Message msg = new Message();
handler.sendMessage(msg);

7. Disconnect
As Socket is in a type which is always connected, no need to disconnect.




Station in Windows with C# to control Camellia Mini Controller which is an Access Point using socket

1. Varify Wi-Fi Hardware
Code in Main Class:
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
string ipAddress = null;
foreach (NetworkInterface adapter in nics)
{
   /// Wi-Fi
   if (adapter.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
   {
      IPInterfaceProperties ip = adapter.GetIPProperties();
      UnicastIPAddressInformationCollection ipCollection = ip.UnicastAddresses;
      foreach (UnicastIPAddressInformation ipadd in ipCollection)
      {
         if (ipadd.Address.AddressFamily == AddressFamily.InterNetwork)
         { 
            ipAddress = ipadd.Address.ToString();
         }
      }
   }
}

2. Set Variables
Code in Main Class:
public Socket clientSocket;
public IPAddress wifiserverIP = IPAddress.Parse("192.168.4.1");
public int wifiPort = 14615;

3. Connect to An Access Point
Code in Main Class:
try
{
   clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
   clientSocket.Connect(wifiserverIP, wifiPort);
}
catch (Exception error)
{
}

4. Send Messages
Code in Main Class:
public bool SocketSendMsg(byte[] data)
{
   if ( (clientSocket == null)&&(clientSocket.Connected) )
   {
      clientSocket.Send(data);
   }
}

5. Receive Messages
Code in Main Class:
Thread receiveThread = new Thread(SocketReceiveMsg);
receiveThread.Start();
Code in Thread:
public bool SocketSendMsg()
{
   byte[] result = new byte[1024];
   if ( (clientSocket == null)&&(clientSocket.Connected) )
   {
      int receiveLength = clientSocket.Receive(result);
      string resultStr = Encoding.Default.GetString(result, 0, receiveLength);
      /// Other Encoding Types 
      // Encoding.ASCII
      // Encoding.UTF8
   }
}
Windows Socket should use the same Encoding Type for Sending and Receiving.

6. Messages among Threads
Code in Main Class:
string resultStr = "My dear Camellia!";
mqttInvoke mi = new mqttInvoke(messageSetText);
BeginInvoke(mi, resultStr);
Code in Thread:
public void messageSetText(string str)
{
   /// str is resultStr in Main Class
}

7. Disconnect
If there is no message for an extended period, it disconnects automatically. Just use the Heart Beat Function to send meanless messages periodically.




Station in iOS and iPadOS with Swift to control Camellia Mini Controller which is an Access Point using socket

1. Varify Wi-Fi Hardware
Code in Main Class:
let reachability = try? Reachability() 
if(reachability != nil){
   if(reachability?.connection == .wifi){
       print("Reachable via WiFi!")
   }
}

let mresult = getMAC()
if((mresult.success)){
   mdevice.text = mresult.ssid
   print("Wi-Fi is OK!")
}

2. Set Variables
Code in Main Class:
let msocket = try? Socket.create()

3. Connect to An Access Point
Code in Main Class:
if(msocket != nil){
   if(msocket!.isConnected == false){
      do{
         try msocket?.connect(to: "192.168.4.1", port: 14615)
         print("Wi-Fi Connect successfully!")
      }
      catch{
         print("Wi-Fi Connect error: ")
         print(error)
      }
   }
}

4. Send Messages
Code in Main Class:
if( (msocket != nil)&&(msocket!.isConnected) ){
   do{
      try msocket?.write(from: writedata)
   }
   catch{
      print("Message Write error:")
      print(error)
   }
 }

5. Receive Messages
Code in Main Class:
if( (msocket != nil)&&(msocket!.isConnected) ){
   var readdata : String = "noresponse"
   do{
      readdata = try (self.msocket?.readString() ?? "noresponse")
      print(readdata)
   }
   catch{
      print("Read error:")
      print(error)
   }
}

6. Disconnect
If there is no message for an extended period, it disconnects automatically. Just use the Heart Beat Function to send meanless messages periodically.





All Core Codes