This is the multi-page printable view of this section. Click here to print...

Return to the regular view of this page

As of 2025-07-24

Scratch

Template code
    This is a template act.

    setup()

    void setup() {
    	/*** SETUP section */
    	tx_busy = false;
    
    	// the twelite main class
    	the_twelite
    		<< TWENET::appid(APP_ID)    // set application ID (identify network group)
    		<< TWENET::channel(CHANNEL) // set channel (physical channel)
    		<< TWENET::rx_when_idle();  // open receive circuit (if not set, it can't listen packets from others)
    
    	// Register Network
    	auto&& nwk = the_twelite.network.use<NWK_SIMPLE>();
    	nwk	<< NWK_SIMPLE::logical_id(0xFE); // set Logical ID. (0xFE means a child device with no ID)
    
    	/*** BEGIN section */
    	Buttons.begin(pack_bits(PIN_BTN), 5, 10); // check every 10ms, a change is reported by 5 consecutive values.
    
    	the_twelite.begin(); // start twelite!
    
    	/*** INIT message */
    	Serial << "--- Scratch act ---" << mwx::crlf;
    }

    Configure the_twelite with application ID APP_ID, wireless channel CHANNEL, and enable reception.

    Also, generate nwk and specify child address 0xFE. This address means a child device without a specified address.

    Also, initialize the Buttons object. This is a chatter suppression algorithm using consecutive references. If the same value is detected 5 times consecutively every 10ms, the port (only PIN_BTN) is confirmed as HIGH or LOW. The function pack_bits(N1, N2, ..) generates a bitmap by 1UL<<N1 | 1UL << N2 | ....

    the_twelite.begin(); // start twelite!
    

    This is the procedure to start the_twelite. Although it did not appear in act0..4, if you configure the_twelite or register various behaviors, always call this.

    begin()

    void begin() {
    	Serial << "..begin (run once at boot)" << mwx::crlf;
    }

    Called only once after setup() at startup. Only displays a message.

    loop()

    Button (switch) input detection

    if (Buttons.available()) {
    	uint32_t bm, cm;
    	Buttons.read(bm, cm);
    
    	if (cm & 0x80000000) {
    		// the first capture.
    	}
    
    	Serial << int(millis()) << ":BTN" << format("%b") << mwx::crlf;
    }

    Using consecutive references by Buttons, the state is confirmed. When the button state changes, output to serial.

    Input from serial

    while(Serial.available()) {
      int c = Serial.read();
    
    	Serial << '[' << char(c) << ']';
    
      switch(c) {
      case 'p': ... // Display millis()
      case 't': ... // Send wireless packet (vTransmit)
            if (!tx_busy) {
    					tx_busy = Transmit();
    					if (tx_busy) {
    						Serial  << int(millis()) << ":tx request success! ("
    										<< int(tx_busy.get_value()) << ')' << mwx::crlf;
     					} else {
    						Serial << int(millis()) << ":tx request failed" << mwx::crlf;;
    					}
    				}
      case 's': ... // Sleep
    				Serial << int(millis()) << ":sleeping for " << 5000 << "ms" << mwx::crlf << mwx::flush;
    				the_twelite.sleep(5000);
    				break;
      }
    }

    If Serial.available() is true, input is stored from the serial port. Read one character from serial and process according to the input character.

    Input ’t’ to send wireless

    When ’t’ is input, transmission is performed. This sample uses a tx_busy flag to avoid continuous input.

    Input ’s’ to sleep

    the_twelite.sleep(5000);

    Sleep for 5000ms = 5 seconds. After waking up, wakeup() is executed.

    wakeup()

    void wakeup() {
    	Serial << int(millis()) << ":wake up!" << mwx::crlf;
    }

    Called first upon waking from sleep. Only displays a message.

    Transmit()

    MWX_APIRET Transmit() {
    	Serial << int(millis()) << ":Transmit()" << mwx::crlf;
    
    	if (auto&& pkt = the_twelite.network.use<NWK_SIMPLE>().prepare_tx_packet()) {
    		// set tx packet behavior
    		pkt << tx_addr(0xFF)  // Broadcast communication
    			<< tx_retry(0x1)    // Retry once
    			<< tx_packet_delay(100,200,20); // Transmit delay between 100-200ms, retry interval 20ms
    
    		// Specify transmission data (decided by application)
    		pack_bytes(pkt.get_payload()
    			, make_pair("SCRT", 4) // 4-character identifier
    			, uint32_t(millis())   // Timestamp
    		);
    
    		// Request transmission
    		return pkt.transmit();
    	} else {
    		// Failed at .prepare_tx_packet() stage (transmission queue full)
    		Serial << "TX QUEUE is FULL" << mwx::crlf;
    	  return MWX_APIRET(false, 0);
    	}
    }

    Minimal procedure to request transmission.

    At the time this function exits, the request has not yet been executed. You need to wait a while. In this example, a delay of 100-200ms before transmission start is set, so transmission will start at the earliest 100ms later.

    on_tx_comp()

    void on_tx_comp(mwx::packet_ev_tx& ev, bool_t &b_handled) {
    	Serial 	<< int(millis()) << ":tx completed!"
    			<< format("(id=%d, stat=%d)", ev.u8CbId, ev.bStatus) << mwx::crlf;
    	tx_busy = false; // clear tx busy flag.
    }

    Called when transmission completes. ev contains transmission ID and completion status.

    on_rx_packet()

    void on_rx_packet(packet_rx& rx, bool_t &handled) {
    	Serial << format("rx from %08x/%d",
    					rx.get_addr_src_long(), rx.get_addr_src_lid()) << mwx::crlf;
    }

    When a packet is received, display the sender’s address information.