I am working on a project, and I am trying to get a grasp of it. Using the WiShield. I have been trying to complete the example program for a simple tweeter. However, I have had no luck yet. I have been trying to find the solutions, and everything I find never seems to work. How do I fix this problem?
My code is below as well as the errors I receive.
Code
#include <WiServer.h>
#define WIRELESS_MODE_INFRA 1
#define WIRELESS_MODE_ADHOC 2
unsigned char local_ip[] = {192,168,2,2};
unsigned char gateway_ip[] = {192,168,2,1};
unsigned char subnet_mask[] = {255,255,255,0};
const prog_char ssid[] PROGMEM = {"myssid"};
unsigned char security_type = 3; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
const prog_char security_passphrase[] PROGMEM = {"mywifipassword"};
prog_uchar wep_keys[] PROGMEM = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Key 3
};
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// Authentication string for the Twitter account.
char* auth = "[user:pass]"; // Base64 encoded USERNAME:PASSWORD
// This function generates a message with the current system time.
void currentTime() {
WiServer.print("Arduino has been running for ");
WiServer.printTime(millis());
}
// A request that sends a tweet using the currentTime function.
TWEETrequest sentMyTweet(auth, currentTime);
void setup() {
// Initialize WiServer (we'll pass NULL for the page serving function since we don't need to serve web pages).
WiServer.init(NULL);
// Enable Serial output and ask WiServer to generate log messages (optional).
Serial.begin(57600);
WiServer.enableVerboseMode(true);
}
// Time (in milliseconds) when the next tweet should be sent.
long tweetTime = 0;
void loop(){
// Check if it's time to sent a tweet
if (millis() >= tweetTime) {
sentMyTweet.submit();
// Send next tweet 5 minutes from now
tweetTime += 1000 * 60 * 5;
}
// Run WiServer
WiServer.server_task();
delay(10);
}
Errors
In file included from SimpleTweeter.cpp:5:
C:\Program Files (x86)\arduino-1.0\libraries\WiShield/WiServer.h:198: error: conflicting return type specified for 'virtual void Server::write(uint8_t)'
C:\Program Files (x86)\arduino-1.0\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
SimpleTweeter.pde:-1: error: 'TWEETrequest' does not name a type
SimpleTweeter.cpp: In function 'void loop()':
SimpleTweeter.pde:-1: error: 'sentMyTweet' was not declared in this scope
(I am new to Arduino.)
It looks like the WiServer library hasn't been upgraded to work with Arduino 1.0. In this version of the Arduino software, the return type of the write method in the Print class was changed from void to size_t.
There is a fork of WiShield on GitHub by Juan C. Muller which makes it compatible with Arduino 1.0.
The subsequent error about the type TWEETrequest is a knock-on effect of this previous error.
Related
I am using the PN532 as an emulator using the emulate_tag_ndef.ino example from arduino. I updated the emulate library according to another post (PN532 emulated card not read by an Android phone) to make it work, but it only works with Android. With iPhones I can only send up to 47 bytes, if succeeded.
Here's how I set the PN532_COMMAND_TGINITASTARGET command:
uint8_t command[] = {
PN532_COMMAND_TGINITASTARGET,
0x05, // MODE: 0x04 = PICC only, 0x01 = Passive only (0x02 = DEP only)
// MIFARE PARAMS
0x04, 0x00, // SENS_RES (seeeds studio set it to 0x04, nxp to 0x08)
0x00, 0x00, 0x00, // NFCID1t (is set over sketch with setUID())
0x20, // SEL_RES (0x20=Mifare DelFire, 0x60=custom)
// FELICA PARAMS
0x01, 0xFE, // NFCID2t (8 bytes) https://github.com/adafruit/Adafruit-PN532/blob/master/Adafruit_PN532.cpp FeliCa NEEDS TO BEGIN WITH 0x01 0xFE!
0x05, 0x01, 0x86,
0x04, 0x02, 0x02,
0x03, 0x00, // PAD (8 bytes)
0x4B, 0x02, 0x4F,
0x49, 0x8A, 0x00,
0xFF, 0xFF, // System code (2 bytes)
0x01, 0x01, 0x66, // NFCID3t (10 bytes)
0x6D, 0x01, 0x01, 0x10,
0x02, 0x00, 0x00,
0x00, // length of general bytes
0x00 // length of historical bytes
}
Does anyone know how I can make the iPhone write to the PN532? I am using the NFC Tools app to write to it. I have tried other apps but without any luck
I have been working through Microsoft's guide on USB Device Emulation and have reached the point that a virtual device shows up in my device manager, but reports an Invalid Device Descriptor.
Can you see any reason why the guide's example descriptor might be invalid?
//In this example, the descriptor declarations are assumed to be global variables,
//declared as shown here for a HID device just as an example:
const UCHAR g_UsbDeviceDescriptor[] = {
// Device Descriptor
0x12, // Descriptor Size
0x01, // Device Descriptor Type
0x00, 0x03, // USB 3.0
0x00, // Device class
0x00, // Device sub-class
0x00, // Device protocol
0x09, // Maxpacket size for EP0 : 2^9
0x5E, 0x04, // Vendor ID
0x39, 0x00, // Product ID
0x00, // LSB of firmware version
0x03, // MSB of firmware version
0x01, // Manufacture string index
0x03, // Product string index
0x00, // Serial number string index
0x01 // Number of configurations
};
I have a problem with my esp8266 project. My purpose is to use esp8266 to transmit beacon frames every one second so that my android device or my laptop can receive it and display in list of APs which i can connect to.
Here is my code I wrote:
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
void setup() {
delay(500);
sendBeacon("ESP8266");
ESP.deepSleep(10e5);
}
void loop() {
}
void sendBeacon(char* ssid) {
// Randomize channel //
byte channel = 1;
wifi_set_channel(channel);
uint8_t packet[128] = { 0x80, 0x00, //Frame Control
0x00, 0x00, //Duration
/*4*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address
/*10*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
/*16*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
/*22*/ 0xc0, 0x6c, //Seq-ctl
//Frame body starts here
/*24*/ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
/*32*/ 0xFF, 0x00, //Beacon interval
/*34*/ 0x01, 0x04, //Capability info
/* SSID */
/*36*/ 0x00
};
int ssidLen = strlen(ssid);
packet[37] = ssidLen;
for(int i = 0; i < ssidLen; i++) {
packet[38+i] = ssid[i];
}
uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
for(int i = 0; i < 12; i++) {
packet[38 + ssidLen + i] = postSSID[i];
}
packet[50 + ssidLen] = channel;
// get SRC MAC
unsigned char mac[6];
WiFi.macAddress(mac);
packet[10] = packet[16] = mac[0];
packet[11] = packet[17] = mac[1];
packet[12] = packet[18] = mac[2];
packet[13] = packet[19] = mac[3];
packet[14] = packet[20] = mac[4];
packet[15] = packet[21] = mac[5];
int packetSize = 51 + ssidLen;
wifi_send_pkt_freedom(packet, packetSize, 0);
delay(1);
}
I used tcpdump to capture those frame and yes, they are there. But I still couldn't see it in list of AP on my laptop and my android device.
I can see it if I stop using deep sleep mode. For example:
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
void setup() {
delay(500);
// sendBeacon("ESP8266");
// ESP.deepSleep(10e5);
}
void loop() {
sendBeacon("ESP8266");
}
void sendBeacon(char* ssid) {
// Randomize channel //
byte channel = 1;
wifi_set_channel(channel);
uint8_t packet[128] = { 0x80, 0x00, //Frame Control
0x00, 0x00, //Duration
/*4*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address
/*10*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
/*16*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
/*22*/ 0xc0, 0x6c, //Seq-ctl
//Frame body starts here
/*24*/ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
/*32*/ 0xFF, 0x00, //Beacon interval
/*34*/ 0x01, 0x04, //Capability info
/* SSID */
/*36*/ 0x00
};
int ssidLen = strlen(ssid);
packet[37] = ssidLen;
for(int i = 0; i < ssidLen; i++) {
packet[38+i] = ssid[i];
}
uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
for(int i = 0; i < 12; i++) {
packet[38 + ssidLen + i] = postSSID[i];
}
packet[50 + ssidLen] = channel;
// get SRC MAC
unsigned char mac[6];
WiFi.macAddress(mac);
packet[10] = packet[16] = mac[0];
packet[11] = packet[17] = mac[1];
packet[12] = packet[18] = mac[2];
packet[13] = packet[19] = mac[3];
packet[14] = packet[20] = mac[4];
packet[15] = packet[21] = mac[5];
int packetSize = 51 + ssidLen;
wifi_send_pkt_freedom(packet, packetSize, 0);
delay(1);
}
Does anyone know why? Please help me to get this, thanks!
First of all, ESP.deepSleep(10e5) makes the processor sleep for 100ms, not a second. The correct would be ESP.deepSleep(10e6). Secondly, you are trying to send just one packet every second or so, it's quite hard to make sure that the wifi reading from the device is gonna get that packet for sure and display it on the list of SSIDs. From my experiments, I had to send three packets every 200ms to make sure it was displayed on my android mobile and pc. You can try to play with the number of packets you send and the interval to see what fits you best...
Also, make sure to configure the ESP correctly at the setup function. When I tried my similar code I had to use two instructions: wifi_set_opmode(STATION_MODE) and wifi_promiscuous_enable(1)
Could you pls help me in this type of task.Actually I dont understand what I should provide as an answer
A given bit vector has length n. It is known that the vector can contain only two ones. A combinational system needs to calculate the distance between the ones. For example, in vector "10100" the distance is 2. Give the high-level specification.
When google turned up this SO question for me, I was pretty excited. I was hoping there'd be some code here I could repurpose. Alas, the OP's question was too abstract for a concrete solution to get proposed.
Still, for the next guy, here's at least /a/ solution, designed for MSVC x64:
#include <intrin.h> // __lzcnt64 & _BitScanForward64
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
/// <summary>
/// Given a pointer to an array of bits, prints out the distance between the bits.
/// </summary>
/// <param name="pBits">Pointer to the bits</param>
/// <param name="len">Length of the array in bytes</param>
/// <param name="carry">Previous value of carry</param>
/// <returns>Final carry</returns>
/// <remarks>Reading right to left, a bit pattern of 11100101 (aka 0xE5) will print 1, 2, 3, 1, 1</remarks>
uint64_t CountBitDistance(const uint8_t* pBits, const size_t len, uint64_t carry = 0)
{
// Assumes len divides evenly by 8. Depending on the platform,
// pBits might also need to be 8 byte aligned. Left as an exercise.
assert((len % 8) == 0);
const uint64_t* pUll = (const uint64_t*)pBits;
for (size_t x = 0; x < len / 8; pUll++, x++)
{
uint64_t ull = *pUll;
// Grab the value before we start modifying ull
const uint64_t newcarry = __lzcnt64(ull);
unsigned long res = 0;
// Returns false when ull is zero. res is zero based.
while (_BitScanForward64(&res, ull))
{
// Tempting though it might be, you can't just increment res and
// do both shifts at once. If the only bit set is the most
// significant one, adding 1 gives you 64. Shifting a 64bit value
// by 64 is undefined behavior in C. On x64 for example, it does
// nothing. If you are *sure* that res will never be 63, or if
// you are on a platform that handles shifts > 63 differently (and
// don't need a portable solution), you could combine them and
// increase perf (by a tiny amount).
// So, first get rid of the zeros...
ull >>= res;
// ... then turn off the bit we just found.
ull >>= 1;
// If we found a bit at position 0, we want to report 1.
res++;
// And apply any carry in from the previous ull.
const uint64_t d = carry + res;
// Carry in applied.
carry = 0;
printf("%llu\n", d);
}
// Remember that we might not go into the loop above at all, so carry
// won't necessarily be zero.
carry += newcarry;
}
// Useful if the source of our bits is continuing to produce data. We may
// need the final value from the previous batch to apply to the next.
return carry;
}
int main()
{
constexpr const uint8_t bits[] = {
0xAA, 0x25, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x42, 0x10, 0x08, 0x08, 0x10, 0x40, 0x00,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xAA, 0x25, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x42, 0x10, 0x08, 0x08, 0x10, 0x40, 0x00,
};
constexpr const uint8_t bits2[] = { 0x2, 0, 0, 0, 0, 0, 0, 0 };
uint64_t t1 = CountBitDistance(bits, sizeof(bits));
printf("t1: %llu\n\n", t1);
uint64_t t2 = CountBitDistance(bits2, sizeof(bits2), t1);
printf("t2: %llu\n", t2);
}
No doubt someone else will pop up with a drastically better solution using some clever bit twiddling hacks. Still, at least now there's something.
I'm attempting to send sensor data from an Arduino Uno via a Copperhead Wi-Fi shield to a specific IP address and port on a LAN.
I can get the Copperhead Wi-Fi Server example sketch to work (pasted below). However, I'm not interested in responding to server requests via HTML. All I'm interested in is setting up a socket-like connection and sending data via TCP or UDP to IP address 192.168.0.3, port 1234.
I'm sure there is an easy solution to this, but as I am new to Arduino and my attempts to find a solution have been unsuccessful.
#include <WiServer.h>
#define WIRELESS_MODE_INFRA 1
#define WIRELESS_MODE_ADHOC 2
// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {192,168,0,2}; // IP address of WiShield
unsigned char gateway_ip[] = {192,168,0,1}; // router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0}; // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"WiFi_AP"}; // max 32 bytes
unsigned char security_type = 0; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"12345678"}; // max 64 characters
// WEP 128-bit keys
// sample HEX keys
prog_uchar wep_keys[] PROGMEM = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, // Key 0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Key 3
};
// Setup the wireless mode
// Infrastructure - connect to AP
// Adhoc - connect to another Wi-Fi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// End of wireless configuration parameters ----------------------------------------
// This is our page serving function that generates web pages
boolean sendMyPage(char* URL) {
// Check if the requested URL matches "/"
if (strcmp(URL, "/") == 0) {
// Use WiServer's print and println functions to write out the page content
WiServer.print("<html>");
WiServer.print("Hello World");
WiServer.print("</html>");
// URL was recognized
return true;
}
// URL not found
return false;
}
void setup() {
// Initialize WiServer and have it use the sendMyPage function to serve pages
WiServer.init(sendMyPage);
// Enable Serial output and ask WiServer to generate log messages (optional)
Serial.begin(57600);
WiServer.enableVerboseMode(true);
}
void loop(){
// Run WiServer
WiServer.server_task();
delay(10);
}
Looks like you are using the WiShield library. There should be an examples folder in the WiShield download with a SocketApp and UDPApp example. This is a good place to start.
A few things I learned while making a UDP app.
You may have to edit some #defines (e.g. APP_UDPAPP in apps-conf.h, UIP_CONF_UDP in uip-conf.h) before recompiling your app.
If you are doing a UDP app, keep in mind that you have a limited receive buffer (UIP_CONF_BUFFER_SIZE in uip-conf.h sets it to 400). My router was sending out a UDP broadcast XML message that was ~700 bytes which caused this buffer to overflow and over write other data. I don't think TCP will have this problem because it will negotiate a MSS that won't overrun the buffer.
In the end I made changes to the handle_connection() function in the UDPapp example. Below is a snippet (with uip_ipaddr set to 255.255.255.255).
void send_state(void) {
sprintf((char*)uip_appdata, "state %ld %ld %ld %c %d",
clock_time(),
state.sensors.ping[0].cm,
state.sensors.ping[1].cm,
state.actuators.chassis.direction,
state.actuators.chassis.speed);
uip_send(uip_appdata, strlen((char*)uip_appdata));
}
void send_beacon(void) {
if(timer_expired(&beacon_timer)) {
timer_reset(&beacon_timer);
sprintf((char*)uip_appdata, "beacon %ld", clock_time());
uip_send(uip_appdata, strlen((char*)uip_appdata));
uip_log("beacon sent");
}
}
boolean data_or_poll(void) {
return (uip_newdata() || uip_poll());
}
static PT_THREAD(handle_connection(void)) {
PT_BEGIN(&s.pt);
PT_WAIT_UNTIL(&s.pt, data_or_poll());
if(uip_newdata()) {
uip_flags &= (~UIP_NEWDATA);
send_state();
} else if (uip_poll()) {
uip_flags &= (~UIP_POLL);
send_beacon();
}
PT_END(&s.pt);
}
Did you get a chance to look at the Arduino WiFiWebClient tutorial? This example shows how to connect to a webserver and send an HTTP GET request.
You could create a simple server on any machine on the LAN and use the client library to connect to the server and send data using the write/print/println set of functions. I know its easier said than done, but thats the fun of programming isnt it?