Friday, November 30, 2018

Operator Overloading in C++

// Assignment operators:
Type &operator&=(Type &lhs, const Type &rhs); // Assign bitwise and
Type &operator^=(Type &lhs, const Type &rhs); // Assign exclusive or
Type &operator|=(Type &lhs, const Type &rhs); // Assign bitwise or
Type &operator-=(Type &lhs, const Type &rhs); // Assign difference
Type &operator<<=(Type &lhs, const Type &rhs); // Assign left shift
Type &operator*=(Type &lhs, const Type &rhs); // Assign product
Type &operator/=(Type &lhs, const Type &rhs); // Assign quotient
Type &operator%=(Type &lhs, const Type &rhs); // Assign remainder
Type &operator>>=(Type &lhs, const Type &rhs); // Assign right shift
Type &operator+=(Type &lhs, const Type &rhs); // Assign sum

//Other modification operators
Type &operator--(Type &lhs); // Prefix decrement - decrement and return new value
Type operator--(Type &lhs, int unused); // Postfix decrement - decrement and return copy of old value
Type &operator++(Type &lhs); // Prefix increment - increment and return new value
Type operator++(Type &lhs, int unused); // Postfix increment - increment and return copy of old value

//Comparison operators
bool operator==(const Type &lhs, const Type &rhs); // Equal
bool operator>(const Type &lhs, const Type &rhs); // Greater than
bool operator>=(const Type &lhs, const Type &rhs); // Greater than or equal
bool operator<(const Type &lhs, const Type &rhs); // less than
bool operator<=(const Type &lhs, const Type &rhs); // less than or equal
bool operator!(const Type &lhs); // logical complement
bool operator!=(const Type &lhs, const Type &rhs); // no equal
//Other operators
Type operator+(const Type &lhs, const Type &rhs); // Addition
Type operator+(const Type &lhs); // Unary plus
Type operator-(const Type &lhs, const Type &rhs); // Subtraction
Type operator-(const Type &lhs); // Unary minus
ContainedType* operator&(const Type &lhs); // Address of
Type operator&(const Type &lhs, const Type &rhs); // Bitwise and
Type operator~(const Type &lhs, const Type &rhs); // Bitwise complement
Type operator^(const Type &lhs, const Type &rhs); // Bitwise exclusive or
Type operator|(const Type &lhs, const Type &rhs); // Bitwise or
Type operator/(const Type &lhs, const Type &rhs); // Division
Type operator<<(const Type &lhs, const Type &rhs); // Left shift
Type operator*(const Type &lhs, const Type &rhs); // Multiplication
ContainedType &operator*(const Type &lhs); // Dereference
Type operator%(const Type &lhs, const Type &rhs); // Remainder
Type operator>>(const Type &lhs, const Type &rhs); // Right shift

class Type
{
 
// Overloads which must be member functions
  ContainedType &operator[](const IndexType &index); // Array subscript
  Type &operator=(const Type &rhs); // Assignment
  ContainedType &operator->*(); // Member reference
  const ContainedType &operator->*() const; // Member reference
  ContainedType &operator->(); // Member reference
  const ContainedType &operator->() const; // Member reference
 
 // Assignment operators
  Type &operator&=(const Type &rhs); // Assign bitwise and
  Type &operator^=(const Type &rhs); // Assign exclusive or
  Type &operator|=(const Type &rhs); // Assign bitwise or
  Type &operator-=(const Type &rhs); // Assign difference
  Type &operator<<=(const Type &rhs); // Assign left shift
  Type &operator*=(const Type &rhs); // Assign product
  Type &operator/=(const Type &rhs); // Assign quotient
  Type &operator%=(const Type &rhs); // Assign remainder
  Type &operator>>=(const Type &rhs); // Assign right shift
  Type &operator+=(const Type &rhs); // Assign sum
//Other modification operators
  Type &operator--(Type &lhs); // Prefix decrement - decrement and return new value
  Type operator--(Type &lhs, int unused); // Postfix decrement - decrement and return copy of old value
  Type &operator++(); // Prefix increment - increment and return new value
  Type operator++(int unused); // Postfix increment - increment and return copy of old value
//Comparison operators
  bool operator==(const Type &rhs) const; // Equal
  bool operator>(const Type &rhs) const; // Greater than
  bool operator>=(const Type &rhs) const; // Greater than or equal 
  bool operator<(const Type &rhs) const; // Less than
  bool operator<=(const Type &rhs) const; // Less than or equal
  bool operator!=(const Type &rhs) const; // Not equal
//Other operators
  Type operator+(const Type &rhs) const; // Addition
  Type operator+() const; // Unary plus
  Type operator-(const Type &rhs) const; // Subtraction
  Type operator-() const; // Unary minus
  ContainedType* operator&(); // Address of
  const ContainedType* operator&() const; // Address of
  Type operator&(const Type &rhs) const; // Bitwise and
  Type operator~(const Type &rhs) const; // Bitwise complement
  Type operator^(const Type &rhs) const; // Bitwise exclusive or
  Type operator|(const Type &rhs) const; // Bitwise or
  ContainedType &operator*(); // Dereference
  const ContainedType &operator*() const; // Dereference
  Type operator/(const Type &rhs) const; // Division
  Type operator<<(const Type &rhs) const; // Left shift
  bool operator!() const; // Logical complement
  Type operator*(const Type &rhs) const; // Multiplication
  Type operator%(const Type &rhs) const; // Remainder
  Type operator>>(const Type &rhs) const; // Right shift
};


Example


Type& Type::operator = (Type const & rhs)
{
    if (&rhs != this)
    {
        // perform assignment to the class T's attributes
    }
    // return by reference
    return *this;
}


Type Type::operator &= (Type const & rhs)
{
    return *this = (*this) & rhs;
}


Type Type::operator & (Type const & rhs)
{
    Type newObjVal;

    // do customized bitwise AND for the type against rhs
    ….

    // return an object by value
    return newObjVal;
}

Type& Type::operator++()  // prefix
{
    ++m_data;
    return *this;
}



class MyClass
{
public:
    // conversion operator, so expression like: Type b = myClass;
    operator Type() { return *m_ptr; }
...
private:
    int m_data;
    Type m_ptr;
};

MyClassMyClass::operator++(int unused)  // postfix
{
    MyClassresult = *this;
    ++m_data;
    // return value before increment
    return result;
}


T* MyClass::operator->() const {return m_ptr; }

// Conversion operator

Tuesday, August 14, 2018

Pointers of String

It is always tricky dealing with string in C/C++, but if we know the rule of evaluation of expression in C++, it's not that hard to understand it.

A string declaration is always evaluated from right to left.  For example, "char *str" is evaluated as "a variable with name 'str' is a pointer (*) of type char".

Another example:

"const char *str" is evaluated as variable str as a pointer of type char that is const (the content is immutable").  (Please remember, "const char .." expression is identical to expression "char const ...")

"char * const str" is evaluated as a variable with name 'str' is a constant pointer to type char, meaning once the pointer is initialized to point to a string, it cannot be changed to point to another string.

"char const * const str" is evaluated as "a variable with name 'str' is a constant pointer to constant char content.  It is a combination to all above.



#include <iostream>

/*

char* str: 
const char* str OR char const *str
char* const str: 
const char* const str: 


*/

#define L(v)       #v << " = " << v

using namespace std;

static char cstr[] = "String ini statis!";

int main()
{
    char*   ps1;  // just a regular pointer to a string
    ps1 = cstr;
    cout << L(ps1) << endl;

#if 0
    char const * p_constr = cstr;
    // the following causes compile error, as it tries to change value of the static string
    *p_constr = '1';
    cout << L(p_constr) << endl;
#endif

    // a dialect of the above (char const *)
    const char* p_constr2 = cstr;
    *p_constr2 = '1';
    cout << L(p_constr2) << endl;


#if 0
    const char* const const_ptr = cstr;  // the pointer cannot be set to different one

    // the following will cause compile error
    const_ptr = cstr2;
    cout << L(const_ptr) << std::endl;
#endif
}

Saturday, June 30, 2018

WeMos D1 WiFi uno based ESP8266 for arduino Compatible



www.aliexpress.com: $7.60, 5 Jan 2016


Docs: http://www.wemos.cc/d1/
http://www.wemos.cc/d1/Getting_Started


  • based on the ESP-8266EX.
  •     Arduino Compatible, you can use it on Arduino IDE.
  •     11 Digital I/O pins
  •     1 Analog Input pin
  •     OTA   -- Wireless Upload(Program)
  •     Onboard switching power supply -- Max 24V input, 5V 1A output 
  •     All GPIOs are 3.3 volts only



cd ~/build
git clone https://github.com/esp8266/Arduino.git esp8266
#cd ~/sketchbook
cd /opt/Arduino/hardware
ln -s ~/build/esp8266 ./esp8266
cd ./esp8266/tools
sudo ./get.py

ARDUINO SKETCH


Board: WeMos D1
CPU Freq: 80 MHz
Upload using: Serial
Upload speed: 115200
Port:
Programmer: USBasp


Compile AVR code (ARDUINO NANO)

$(TOOLCHAIN_DIR)/avr-g++ -c -g -Os -std=gnu++11 -fno-exceptions \
    -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega328p \
    -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR \
    "-I/opt/Arduino/hardware/arduino/avr/cores/arduino" \
    "-I/opt/Arduino/hardware/arduino/avr/varians/eightanaloginputs" 
    <C/C++ source> -o <.o file>

TOOLCHAIN_DIR = /opt/Arduino/hardware/tools/avr/bin
                    or
                /usr/bin

UPLOAD

with avrdude:

/usr/bin/avrdude -q -V -p atmega328p -C /etc/avrdude.conf -D -c arduino -b 57600 -P /dev/ttyUSB0 \
-U flash:w:build-nano-atmega328/Blink.hex:i

make show_boards

Thursday, June 28, 2018

ESP32 from Espressif Systems

This beast is really awesome.  For about $6 (on eBay), we can get a full functional IoT system using ESP32 application SoC made by a Chinese company called Espressif.  The CPU core is based on XTensa architecture.  XTensa is a CPU/MCU architecture designed by a Silicon Valley-based company named Cadence Tensilica.  Cadence Tensilica, according to Wikipedia, was founded by the former co-founder of the MIPS Technologies (one of the first player in RISC CPU architecture), Chris Rowen.

Espressif bought the IP rights to use in their own SoC products such as in ESP32 series. ESP32 itself is an evolutional product of its predecessor, ESP8266.  A lot of features in this tiny SoC, such as WiFi & Bluetooth,  cryptographic co-processor, Hall sensor, generous amount of ADC inputs (but multiplexed with other GPIOs), 2 DAC outputs, SPI, I2S, I2C,  ultra-low power coprocessor, Ethernet MAC MII interface (but we need to add PHY interface to connect to a medium), temperature sensor, touch sensors, CAN, 4 MB flash, etc.

Another interesting and cool thing is there a bunch of toolkits, SDK etc., including FreeRTOS support.  Configuring the device can be as easy with menu-driven a-la Linux Kernel.

The Extensa ISA is actually a hybrid of RISC and CISC ISA.  As detailed in the documents at Github, about it has about 80 RISC instructions with length 24 or 16-bit (unlike common RISC instructions which uniformly 32 bits).  The architecture let the SoC designers customize it to add several extended CISC instructions to speed up and save memory space.  The CPU endianness is also changeable between Little and Big endian.

The extended instructions, among others, are to support MAC (Multiply-Accumulate) which is common in DSP applications and other media processing operations.  Another thing is the support for coprocessors.

Below is an example to blink the onboard LED (GPIO2) with FreeRTOS:


/* Blink Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"

/* Can run 'make menuconfig' to choose the GPIO to blink,
   or you can edit the following line and set a number here.
*/
#define BLINK_GPIO CONFIG_BLINK_GPIO

void blink_task(void *pvParameter)
{
    /* Configure the IOMUX register for pad BLINK_GPIO (some pads are
       muxed to GPIO on reset already, but some default to other
       functions and need to be switched to GPIO. Consult the
       Technical Reference for a list of pads and their default
       functions.)
    */
    gpio_pad_select_gpio(BLINK_GPIO);
    /* Set the GPIO as a push/pull output */
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
    while(1) {
        /* Blink off (output low) */
        gpio_set_level(BLINK_GPIO, 0);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        /* Blink on (output high) */
        gpio_set_level(BLINK_GPIO, 1);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void app_main()
{
    xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
}



As described in https://www.freertos.org/a00125.html,  the format of task creation API is:

BaseType_t xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, unsigned short usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask )

Each task is assigned a priority from 0 to ( configMAX_PRIORITIES - 1 ), where 0 is the lowest priority and configMAX_PRIORITIES is defined within FreeRTOSConfig.h:

/* This has impact on speed of search for highest priority */
#ifdef SMALL_TEST
#define configMAX_PRIORITIES ( 7 )
#else
#define configMAX_PRIORITIES ( 25 )

#endif

Low priority numbers denote low priority tasks. The idle task has priority zero (tskIDLE_PRIORITY).

Sunday, June 10, 2018

Regular Expression in C++

RegexDemo.h:


#ifndef REGEXDEMO_H
#define REGEXDEMO_H

#include <iostream>
#include <string>
#include <regex>

class RegexDemo
{
    public:
        /** Default constructor */
        RegexDemo(char const *str) : m_str(str), m_matches() {};
        RegexDemo(std::string const & str);
        /** Default destructor */
        virtual ~RegexDemo();

        bool match(std::string const & pattern)
        {
            return match(pattern.c_str());
        }
        bool match(char const * pattern);

        std::cmatch& get_cmatch() { return m_matches; }

        friend std::ostream& operator<<(std::ostream& ios, std::cmatch const & cm);
    protected:

    private:
        std::string     m_str;
        std::cmatch     m_matches;
        std::regex_constants::match_flag_type flag = std::regex_constants::match_any;
};


std::ostream& operator<<(std::ostream& ios, std::cmatch const & cm);

#endif // REGEXDEMO_H


RegexDemo.cpp:


#include "RegexDemo.h"

RegexDemo::RegexDemo(std::string const & str) :
    m_str(str), m_matches()
{
    //ctor
}

RegexDemo::~RegexDemo()
{
    //dtor
}


#if 0
bool RegexDemo::match(std::string const & pattern)
{
    std::regex exp(pattern);
    return std::regex_match(m_str, exp);
}
#endif


bool RegexDemo::match(char const * pattern/*, std::cmatch &cm*/)
{
    std::regex exp(pattern);
    return std::regex_match(m_str.c_str(), m_matches, exp, flag);
}


std::ostream& operator<<(std::ostream& ios, std::cmatch const & cm)
{
    for(unsigned i=0; i< cm.size(); ++i)
    {
        ios << "[" << cm[i] << "] ";
    }

    return ios;
}


main.cpp:

#include <iostream>
#include "RegexDemo.h"

using namespace std;

int main()
{
    RegexDemo reg("Hello, World Ahsan,123Bae!");

    std::cout << "Match1: " << reg.match(".*123!") << std::endl;

    std::cmatch matches;
    if (reg.match("(.*),([0-9]+)(.*)"))
    {
        std::cout << "The matches were: " << reg.get_cmatch() << std::endl;
        std::cout << "The number is " << reg.get_cmatch()[2] << std::endl;
    }
    return 0;
}

The Output


$ ./myregex 
Match1: 0
The matches were: [Hello, World Ahsan,123Bae!] [Hello, World Ahsan] [123] [Bae!] 
The number is 123

Saturday, May 19, 2018

How to build wxWidgets for Windows

For sure we need Visual Studio installed (get the community edition for free).  After we install the source code package (e.g, in B:\WxWidgets-3.0.4)

Steps to build:

  1. Open "x64 Native Tools Command Prompt for VS ..." Command shell (just type in the Cortana search)
  2. Change to the wxWidgets directory
  3. type: 
b:
cd wxWidgets-3.0.4\build\msw

nmake /f makefile.vc

After it finishes, just set WXWIN environment variable to poin to that directory (e.g, B:\WxWidgets-3.0.4)



Thursday, May 10, 2018

How to print ClassName


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef __CNAME_H__
#define __CNAME_H__

#include <string>


inline std::string className(const std::string& prettyFunction)
{
    size_t colons = prettyFunction.find("::");
    if (colons == std::string::npos)
        return "::";

    size_t begin = prettyFunction.find_last_of("::") + 1;
    return prettyFunction.substr(begin);
}

#ifdef __GNUC__
#define __CLASS_NAME__ className(__PRETTY_FUNCTION__)
#define __FUNCNAME__ __PRETTY_FUNCTION__
#else
#define __CLASS_NAME__ className(__FUNCTION__)
#define __FUNCNAME__ __FUNCTION__
#endif

#endif

Vector of Smart Pointers with Template


#include <iostream>
#include <vector>
#include <memory>
#include <sstream>
#include <string>
#include <typeinfo>


// Require C++ version 14 to compile!

class Base
{
public:
    Base(Base & other);
    Base(Base *);
    Base(char const * const tag, char const * const desc) : m_tag(tag), m_desc(desc) {}
    //Base(std::string const & tag, std::string const & desc) : m_tag(tag), m_desc(desc) {}
    ~Base() = default;

    void print();
    virtual void Process(); 

public:
    std::string m_tag = "";
    std::string m_desc = "";
};



Base::Base(Base & rhs)
{
    m_tag = rhs.m_tag;
    m_desc = rhs.m_desc;
}


Base::Base(Base *pOther)
{
    m_tag = pOther->m_tag;
    m_desc = pOther->m_desc;
}


void Base::print()
{
    std::cout << __FUNCTION__ << "(" << this << "): Base::m_tag = " << m_tag << std::endl 
              << "                  Base::m_desc = " << m_desc << std::endl;
}


void Base::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}



template <class CNAME>
Base* createClass(char const *const tag, char const * const desc)
{
    CNAME * pObj  = new CNAME(tag,desc);

    std::cout << "Inside " << __FUNCTION__  << "(): ";
    pObj->Process();
    return dynamic_cast<Base*>(pObj);
}


template <class CNAME>
std::unique_ptr<Base> createUniqueClass(char const *const tag, char const *const desc)
{
    std::unique_ptr<Base> obj(createClass<CNAME>(tag, desc));
    return obj;
}



class KelasA : public Base
{
public:
    KelasA(char const * const tag, char const * const desc) : Base(tag, desc) {}
 static std::string const DefaultKelasName;

    void Process() override;
private:
 std::string m_name = DefaultKelasName;
};

std::string const KelasA::DefaultKelasName = "A";




void KelasA::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


class KelasB : public Base
{
public:
    KelasB(char const * const tag, char const * const desc) : Base(tag, desc) {}
 static std::string const DefaultKelasName;
    void Process() override;
private:
 std::string m_name = DefaultKelasName;
};


std::string const KelasB::DefaultKelasName = "B";


void KelasB::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


class Container
{
public:
 template <class CNAME>
 void Add(std::string tag = "")
 {
  std::ostringstream sout;
  sout << __FUNCTION__ << ":Entry=" << m_bin.size();
  #define ANAM(x) #x
  m_bin.push_back(createUniqueClass<CNAME>(tag.c_str(), const_cast<char const *>(sout.str().c_str())));
 }

 void Process();


private:
    std::vector<std::unique_ptr<Base>> m_bin;
};



void Container::Process()
{
 for(auto & v : m_bin)
    {
        v->Process();
        v->print();
    }
}


int main()
{
 Container c;

 for(auto i = 0; i<10; ++i)
 {
  c.Add<KelasA>("A");
  c.Add<KelasB>("B");
 }

 c.Process();
 
    return 0;
}

Vector of Smart Pointers (revised)

The previous example doesn't really show the polymorphism. This example shows the coolness of C++ (version 14):





#include <iostream>
#include <vector>
#include <memory>


// Require C++ version 14 to compile!

class Base
{
public:
    Base(Base & other);
    Base(Base *);
    Base(char const * const tag, char const * const desc) : m_tag(tag), m_desc(desc) {}
    ~Base() = default;

    void print();
    virtual void Process(); 

public:
    std::string m_tag = "";
    std::string m_desc = "";
};



Base::Base(Base & rhs)
{
    m_tag = rhs.m_tag;
    m_desc = rhs.m_desc;
}


Base::Base(Base *pOther)
{
    m_tag = pOther->m_tag;
    m_desc = pOther->m_desc;
}


void Base::print()
{
    std::cout << __FUNCTION__ << "(" << this << "): Base::m_tag = " << m_tag << std::endl 
              << "                  Base::m_desc = " << m_desc << std::endl;
}


void Base::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}



template <class CNAME>
Base* createClass(char const *const tag, char const * const desc)
{
    CNAME * pObj  = new CNAME(tag,desc);

    std::cout << "Inside " << __FUNCTION__  << "(): ";
    pObj->Process();
    return dynamic_cast<Base*>(pObj);
}


template <class CNAME>
std::unique_ptr<Base> createUniqueClass(char const *const tag, char const *const desc)
{
    std::unique_ptr<Base> obj(createClass<CNAME>(tag, desc));
    return obj;
}



class KelasA : public Base
{
public:

    KelasA(char const * const tag, char const * const desc) : Base(tag, desc) {}
    void Process() override;
};


void KelasA::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


class KelasB : public Base
{
public:
    KelasB(char const * const tag, char const * const desc) : Base("B", desc) {}
    void Process() override;
};



void KelasB::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}




int main()
{
    std::vector<std::unique_ptr<Base>> vb;

    vb.push_back(createUniqueClass<KelasA>("A", "Kelase A-1"));

    vb.push_back(createUniqueClass<KelasB>("B", "Kelase B-1"));

    //for(auto v = vb.begin(); v != vb.end(); v++)a
    for(auto & v : vb)
    {
        v->Process();
        v->print();
    }

    return 0;
}

Wednesday, May 9, 2018

Vector of Smart Pointers

#include <iostream>
#include <vector>
#include <memory>


// Require C++ version 14 to compile!

class Base
{
public:
    Base(Base & other);
    Base(Base *);
    Base(char const * const tag, char const * const desc) : m_tag(tag), m_desc(desc) {}

    void print();

public:
    std::string m_tag = "";
    std::string m_desc = "";
};



Base::Base(Base & rhs)
{
    m_tag = rhs.m_tag;
    m_desc = rhs.m_desc;
}


Base::Base(Base *pOther)
{
    m_tag = pOther->m_tag;
    m_desc = pOther->m_desc;
}


void Base::print()
{
    std::cout << __FUNCTION__ << "(" << this << "): Base::m_tag = " << m_tag << std::endl 
              << "                  Base::m_desc = " << m_desc << std::endl;
}


template <class CNAME>
Base * createClass(char const *const tag, char const * const desc)
{
    CNAME *pObj = new CNAME(tag,desc);

    Base *pBase = dynamic_cast<Base*>(pObj);

    return pBase;
}




class KelasA : public Base
{
public:

    KelasA(char const * const tag, char const * const desc) : Base(tag, desc) {}
    void FuncA() {}
};

class KelasB : public Base
{
public:
    KelasB(char const * const tag, char const * const desc) : Base("B", desc) {}
    void FuncA() {}
};


int main()
{
    std::vector<std::unique_ptr<Base>> vb;

    std::unique_ptr<Base> p;
    p = std::make_unique<Base>((createClass<KelasA>("A", "Kelas A-1")));
    vb.push_back(std::move(p));
    p = std::make_unique<Base>((createClass<KelasB>("B", "Kelas B-1")));
    vb.push_back(std::move(p));

    for(auto v = vb.begin(); v != vb.end(); v++)
    {
        (*v)->print();
    }

    return 0;
}

Sunday, April 8, 2018

Stream of Prime Numbers

Create an endless stream of prime numbers - a bit like IntStream.of(2,3,5,7,11,13,17), but infinite. The stream must be able to produce a million primes in a few seconds.

Tuesday, October 3, 2017

ESP8266 vs ESP32

SpecificationsESP8266ESP32
MCUXtensa Single-core 32-bit L106Xtensa Dual-Core 32-bit LX6 with 600 DMIPS
802.11 b/g/n Wi-FiYes, HT20Yes, HT40
WiFi Security?WEP, WPA/WPA2 PSK/Enterprise
Hardware Accelerated Encryption?AES/SHA2/Elliptical Curve Cryptography/RSA-4096
BluetoothNonedual-mode: Bluetooth 4.2 BLE or classi
Typical Frequency80 MHz240 MHz
SRAM160 KB520 KB
FlashSPI Flash, up to 16 MBSPI Flash, up to 16 MB, memory mapped to CPU code space.
GPIO1736
Hardware/Software PWMNone/8 channels1/16 channels
SPI/I2S/I2C/UART 2/1/2/2 3/2/2/3
ADC10 bit12-bit, 18 channels
DACNone2
CANNone?
Ethernet MAC Interface None 1
Touch Sensor None Yes
Temperature SensorNoneyes
Working Temperature-40 C - 125 C-40 C - 125 C
Operating Voltage?2.3V to 3.6V C
Power Consumption 77 Î¼A5 μA power consumption in Deep-sleep

Reference: http://espressif.com/en/products/hardware/esp32/overview

My protoboard


Friday, September 29, 2017

ZigBee for IoT

The ZigBee and Z-Wave short-range wireless technologies are used for remote monitoring and control. However, their specifications and applications are different. Both technologies are ideal for home-area networks (HANs), which is becoming an in.


Differences between ZigBee and Z-Wave:


TechnologyFrequencyModulationData RateRangeApplications
ZigBee902 to 928 MHz (Americas and Australia)2.4 - 2.483 GHz (ISM)BPSK (900 MHz band) or
OQPSK (2.4 GHz band)
250 kbps10 mHome Automation, Smart Grid, Remote control
Z-Wave908.42 MHzGFSK9.6/40 kbps30 mHome Automation, security


ZigBee
It is ratified in the IEEE’s 802.15.4 personal-area network (PAN) radio standard. ZigBee is an open wireless standard from the ZigBee Alliance. The IEEE 802.15.4 standard provides layer 1 (physical layer, or PHY) and layer 2 (media access controller, or MAC) of the network, while the ZigBee stack software provides the network and application layers.

The Zigbee protocol is designed to communicate data through hostile RF environments that are common in commercial and industrial applications.

Zigbee protocol features include:
  • Support for multiple network topologies such as point-to-point,
  • point-to-multipoint and mesh networks
  • Low duty cycle – provides long battery life
  • Low latency
  • Direct Sequence Spread Spectrum (DSSS)
  • Up to 65,000 nodes per network
  • 128-bit AES encryption for secure data connections
  • Collision avoidance, retries, and acknowledgments (CSMA/CA)

ZigBee Physical Layer
ZigBee PHY operates in various bands, but the most common one is in the 2.4 GHz band. It uses offset quadrature phase-shift keying (OQPSK) that transmits two bits per symbol. In 900 MHz band, it uses BPSK for modulation.  The radio uses DSSS for digital streaming.

There are three (3) kind of devices in ZigBee:
  1. ZigBee Coordinator (ZR)
  2. ZigBee Router (ZR)
  3. ZigBee End Device (ZED)

Tuesday, September 26, 2017

Hot skills in Embedded and IoT

Based on my observation in the job market, the following skills are currently in demand in embedded systems surrounding IoT development:

  1. 802.11 (WiFi)
  2. Bluetooth, especially Bluetooth 4.0 + Low Energy (BLE) or newer
  3. Zigbee (IEEE 802.15.4)
  4. Z-Wave: Based on ITU G.9959 (PHY) and Z-Wave Application layer
  5. Bonjour (mDNS/DNS-SD)
  6. SSDP (Simple Service Discovery Protocol)
  7. OCF (Open Connectivity Foundation's uPnP Device Control Protocol)
  8. TCP/UDP
  9. TLS (Transport Layer Security)
  10. CoAP (Constrained Application Protocol; RFC-7252)
  11. HTTP, especially RESt API
  12. MQTT (Mosquitto)
  13. MultiThread
  14. Websockets
  15. RESTful (Representational State Transfer) architecture
  16. Rust (Rust is a programming language that’s focused on safety, speed, and concurrency)
  17. Jenkins
  18. XML
  19. LWM2M
  20. SQS
  21. AMQP
  22. Kafka
  23. AWS (Amazon Web Service)
  24. Microsoft Azure
  25. I2C
  26. SPI
  27. Asynchronous serial/UART programming
  28. Linux Kernel and Driver development