I wrote a program in C++ for a project and it seems to be giving me some issues running it on my Raspberry Pi 3 B+.
The problem is, the program is actually a countdown timer and it is not supposed to be shut down, but after only 30 minutes, the program stops working.
#include "led-matrix.h"
#include "graphics.h"
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <time.h>
#include <algorithm>
#include <string>
#include <curl/curl.h>
#include <jsoncpp/json/json.h>
#include <jsoncpp/json/reader.h>
#include <jsoncpp/json/writer.h>
#include <jsoncpp/json/value.h>
#include <sstream>
#include <fstream>
#define times 1 //numar de treceri
using namespace std;
using namespace rgb_matrix;
static int usage(const char *progname) {
fprintf(stderr, "usage: %s [options]\n", progname);
fprintf(stderr, "Reads text from stdin and displays it. "
"Empty string: clear screen\n");
fprintf(stderr, "Options:\n");
rgb_matrix::PrintMatrixFlags(stderr);
fprintf(stderr, "\t-f <font-file> : Use given font.\n");
return 1;
}
static int last_id = 53;
Color color(255, 255, 255);
Color color_line(255, 255, 255);
Color color_clock(255, 255, 255);
Color bg_color(0, 0, 0);
const char *bdf_font_file_text = "/home/pi/ct/fonts/9x15B.bdf";
const char *bdf_font_file_clock = "/home/pi/ct/fonts/7x13B.bdf";
const int char_width_text = 9;
const int char_width_clock = 7;
const int char_height_clock = 13;
const string def_message = "100 Pentru Viitor / RomânEști oriunde ai fi!";
int brightness = 100;
int letter_spacing = 0;
int size_of_clock;
string time_result = "";
int year = 100;
int day = 0;
int hour = 0;
int mins = 0;
int sec = 0;
double last_time_text = clock();
double last_time_clock = clock();
double last_time_db = clock();
double last_time_timer = clock();
string last_result = "";
bool countdown = false;
bool random_set = false;
int times_left = times; //numarul de treceri
rgb_matrix::Font font_text;
rgb_matrix::Font font_clock;
char remTime[16];
ofstream timeFile;
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
((std::string *) userp)->append((char *) contents, size * nmemb);
return size * nmemb;
}
// convert int to string (e bine sa stii de el)
static string itos(int i) {
stringstream s;
s << i;
return s.str();
}
//cauta sa vada daca exista deja un timp de la care sa ii dea reset
//preia textul de la API
static string getApiText(int id) {
if (random_set) {
id = 0;
}
try {
CURL *curl;
std::string readBuffer;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, ("http://192.168.0.108/capsula/api.php?order=ASC&id=" + itos(id)).c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
Json::Value root;
Json::Reader reader;
bool parsingSuccessful = reader.parse(readBuffer.c_str(), root); //parse process
if (!parsingSuccessful) {
std::cout << "Failed to parse"
<< reader.getFormattedErrorMessages();
cout << readBuffer.c_str() << endl << endl;
return def_message;
}
if (root[0].get("mesaj", "") != "Start Capsula-Timpului NOW") {
if (random_set) {
int no = 0 + (rand() % static_cast<int>(root.size() + 1));
cout << "random no is " << no << endl;
cout << "random id is " << root[no].get("id", "").asString() << " and last_id is " << last_id
<< endl << endl;
return root[no].get("mesaj", "").asString();
} else if (!random_set) {
last_id = atoi(root[0].get("id", last_id).asString().c_str());
cout << "last_id is " << last_id << endl;
string result = root[0].get("mesaj", "").asString();
last_result = result;
if (result == "") {
random_set = true;
return "";
} else {
random_set = false;
return result;
}
}
} else {
return def_message;
}
last_id = atoi(root[0].get("id", last_id).asString().c_str());
}
return def_message;
}
catch (const std::exception &e) {
if (last_result != "")
return last_result;
else return def_message;
}
}
//aici e triggerul pt countdown
static void checkCountDownStatus() {
try {
CURL *curl;
std::string readBuffer;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.108/capsula/api.php?order=ASC");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
Json::Value root;
Json::Reader reader;
bool parsingSuccessful = reader.parse(readBuffer.c_str(), root); //parse process
if (!parsingSuccessful) {
std::cout << "Failed to parse"
<< reader.getFormattedErrorMessages();
}
for (unsigned int no = 0; no < root.size(); no++) {
string result = root[no].get("mesaj", "").asString();
if (result == "Start Capsula-Timpului NOW") {
//if (result == "bbb") {
//if (result == "Porneste!") {
countdown = true;
}
}
}
}
catch (const std::exception &e) {}
}
//aici calculeaza timpul ramas in countdown timer
static string getRemainingTime() {
if (!countdown) { //cand nu face countdown, o sa afiseze "100:000:00:00:00"
return "100:000:00:00:00";
}
//basic computation pentru countdown
if (clock() - last_time_timer > 1301236) {
sec--;
if (sec < 0) {
sec = 59;
mins--;
}
if (mins < 0) {
mins = 59;
hour--;
}
if (hour < 0) {
hour = 23;
day--;
}
if (day < 0) {
if (year % 4 == 0)
day = 366;
else day = 365;
year--;
}
if (year < 0) {
countdown = false;
}
last_time_timer = clock();
}
//formatare (pt estetica) a countdown-ului
time_result = "";
if (year < 100 && year > 10) {
time_result = time_result + "0" + itos(year);
} else if (year < 10) {
time_result = time_result + "00" + itos(year);
} else time_result = time_result + itos(year);
time_result = time_result + ":";
if (day < 100 && day > 10) {
time_result = time_result + "0" + itos(day);
} else if (day < 10) {
time_result = time_result + "00" + itos(day);
} else time_result = time_result + itos(day);
time_result = time_result + ":";
if (hour < 10) {
time_result = time_result + "0" + itos(hour);
} else time_result = time_result + itos(hour);
time_result = time_result + ":";
if (mins < 10) {
time_result = time_result + "0" + itos(mins);
} else time_result = time_result + itos(mins);
time_result = time_result + ":";
if (sec < 10) {
time_result = time_result + "0" + itos(sec);
} else time_result = time_result + itos(sec);
std::ofstream out("/home/pi/ct/time.txt");
out << time_result;
out.close();
return time_result;
}
//aici compara last_id cu ultimul id din baza de date
static void compareIdToDB() {
try {
CURL *curl;
std::string readBuffer;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, ("http://192.168.0.108/capsula/api.php?order=ASC&id=" + itos(last_id)).c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
Json::Value root;
Json::Reader reader;
bool parsingSuccessful = reader.parse(readBuffer.c_str(), root); //parse process
if (!parsingSuccessful) {
std::cout << "Failed to parse" << reader.getFormattedErrorMessages();
}
int id = atoi(root[0].get("id", -1).asString().c_str());
if (id > -1) {
random_set = false;
cout << "Found new entry" << endl;
}
}
}
catch (const std::exception &e) {}
}
//aici isi face load la fonturi
static int loadFonts() {
if (!font_text.LoadFont(bdf_font_file_text)) {
fprintf(stderr, "Couldn't load text font '%s'\n", bdf_font_file_text);
return 1;
}
if (!font_clock.LoadFont(bdf_font_file_clock)) {
fprintf(stderr, "Couldn't load clock font '%s'\n", bdf_font_file_clock);
return 1;
}
return 0;
}
//aici e main-ul
int main(int argc, char *argv[]) {
RGBMatrix::Options matrix_options;
rgb_matrix::RuntimeOptions runtime_opt;
if (!rgb_matrix::ParseOptionsFromFlags(&argc, &argv, &matrix_options, &runtime_opt)) {
return usage(argv[0]);
}
loadFonts();
RGBMatrix *canvas = rgb_matrix::CreateMatrixFromOptions(matrix_options, runtime_opt);
if (canvas == NULL)
return 1;
canvas->SetBrightness(brightness);
canvas->SetPWMBits(1);
int panel_size = 512;
int x = panel_size;
string remTimeString;
string temp = getApiText(last_id);
char line[1024];
strncpy(line, temp.c_str(), sizeof(line));
line[sizeof(line) - 1] = 0;
int text_offset = (1024 - std::count(line, line + 1024, 0)) * char_width_text;
while (true) {
if (clock() - last_time_text > 50000) { //delay intre schimbare de pixeli
last_time_text = clock();
if (x > 0 - text_offset) {
x--;
} else {
times_left--;
x = panel_size;
if (times_left <= 0) {
temp = getApiText(last_id);
strncpy(line, temp.c_str(), sizeof(line));
line[sizeof(line) - 1] = 0;
text_offset = (1024 - std::count(line, line + 1024, 0)) * char_width_text;
times_left = times; //numar de treceri
}
}
}
if (clock() - last_time_clock > 1301236) { //delay intre "secunde"
remTimeString = getRemainingTime();
size_of_clock = remTimeString.size();
strncpy(remTime, remTimeString.c_str(), sizeof(remTime));
last_time_clock = clock();
if (!countdown)
checkCountDownStatus();
}
if (clock() - last_time_db > CLOCKS_PER_SEC && (random_set)) { //delay intre comaparari la baza de date
compareIdToDB();
last_time_db = clock();
}
rgb_matrix::DrawText(canvas, font_text, x, 16 + font_text.baseline(),
color, &bg_color, line,
letter_spacing);
//draw line
rgb_matrix::DrawLine(canvas, 0, 14, panel_size, 14, color_line);
rgb_matrix::DrawLine(canvas, 0, 15, panel_size, 15, color_line);
//show clock
rgb_matrix::DrawText(canvas, font_clock, 126 - (size_of_clock * char_width_clock) - 6, 12,
color_clock, &bg_color, remTime,
letter_spacing);
rgb_matrix::DrawText(canvas, font_clock, 254 - (size_of_clock * char_width_clock) - 6, 12,
color_clock, &bg_color, remTime,
letter_spacing);
rgb_matrix::DrawText(canvas, font_clock, 382 - (size_of_clock * char_width_clock) - 6, 12,
color_clock, &bg_color, remTime,
letter_spacing);
rgb_matrix::DrawText(canvas, font_clock, 510 - (size_of_clock * char_width_clock) - 6, 12,
color_clock, &bg_color, remTime,
letter_spacing);
}
}
Is there any way to tell Raspbian (the OS) that it should NOT pause the process?
I'm just speaking my mind out here, honestly I have no idea what is going on.
The worst part, the problem started showing up 1 hour before the countdown is supposed to start...
Related
On Windows I am able to enumerate removable drives using FindFirstVolume, FindNextVolume, GetVolumePathNamesForVolumeName and the GetDriveType functions. How can I achieve this on Linux and macOS?
On macOS you need to work with IOKit: https://developer.apple.com/documentation/iokit
It can looks like the following code:
#include <cstdlib>
#include <iostream>
#include <mach/mach_port.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOTypes.h>
#include <IOKit/IOKitKeys.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>
std::string get_descriptor_idx(IOUSBDeviceInterface **dev, UInt8 idx);
int main(int argc, char *argv[]) {
/*
* Get the IO registry
*/
auto entry = IORegistryGetRootEntry(kIOMasterPortDefault);
if (entry == 0)
return EXIT_FAILURE;
io_iterator_t iter{};
auto kret = IORegistryEntryCreateIterator(entry, kIOUSBPlane, kIORegistryIterateRecursively, &iter);
if (kret != KERN_SUCCESS || iter == 0)
return EXIT_FAILURE;
io_service_t service {};
std::cout << std::endl;
while ((service = IOIteratorNext(iter))) {
IOCFPlugInInterface **plug = nullptr;
IOUSBDeviceInterface **dev = nullptr;
io_string_t path;
SInt32 score = 0;
IOReturn ioret;
kret = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plug, &score);
IOObjectRelease(service);
if (kret != KERN_SUCCESS || plug == nullptr) {
continue;
}
/*
* USB
*/
ioret = (*plug)->QueryInterface(plug, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
static_cast<LPVOID *>((void *) &dev));
(*plug)->Release(plug);
if (ioret != kIOReturnSuccess || dev == nullptr) {
continue;
}
if (IORegistryEntryGetPath(service, kIOServicePlane, path) != KERN_SUCCESS) {
(*dev)->Release(dev);
continue;
}
std::cout << "USB Path: " << path << std::endl;
UInt8 si;
UInt16 u16v;
if ((*dev)->GetDeviceVendor(dev, &u16v) == kIOReturnSuccess)
std::cout << "VID: "<< u16v << std::endl;
if ((*dev)->GetDeviceProduct(dev, &u16v) == kIOReturnSuccess)
std::cout << "PID: "<< u16v << std::endl;
if ((*dev)->USBGetManufacturerStringIndex(dev, &si) == kIOReturnSuccess) {
std::cout << "Manufacturer: " << get_descriptor_idx(dev, si) << std::endl;
}
if ((*dev)->USBGetProductStringIndex(dev, &si) == kIOReturnSuccess) {
std::cout << "Product: " << get_descriptor_idx(dev, si) << std::endl;
}
(*dev)->Release(dev);
std::cout << std::endl;
}
IOObjectRelease(iter);
return 0;
}
/* a quick version */
std::string get_descriptor_idx(IOUSBDeviceInterface **dev, UInt8 idx)
{
IOUSBDevRequest request;
IOReturn ioret;
char buffer[4086] = { 0 };
CFStringRef cfstr;
CFIndex len;
request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
request.bRequest = kUSBRqGetDescriptor;
request.wValue = (kUSBStringDesc << 8) | idx;
request.wIndex = 0x409;
request.wLength = sizeof(buffer);
request.pData = buffer;
ioret = (*dev)->DeviceRequest(dev, &request);
if (ioret != kIOReturnSuccess)
return "n/a";
if (request.wLenDone <= 2)
return "n/a";
cfstr = CFStringCreateWithBytes(nullptr, (const UInt8 *)buffer+2, request.wLenDone-2, kCFStringEncodingUTF16LE, 0);
len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), kCFStringEncodingUTF8) + 1;
if (len < 0) {
CFRelease(cfstr);
return "n/a";
}
std::string str; str.resize(len);
CFStringGetCString(cfstr, str.data(), len, kCFStringEncodingUTF8);
CFRelease(cfstr);
return str;
}
In my case the result ıs:
USB Path: IOService:/AppleARMPE/arm-io/xxxx/USB2.1 Hub#01100000
VID: 1507
PID: 1552
Manufacturer: GenesysLogic
Product: USB2.1 USB
I have a problem. I'm working with Arduino but i'm not good with C++ and i take a error. I work on active security system. I used to motion sensor, RFID, embedded clock and wifi modele. But i say, i take a error Can you help me ?
#include <SoftwareSerial.h>
#include <MFRC522.h>
#include <SPI.h>
#include <virtuabotixRTC.h>
String agAdi = "";
String agSifresi = "";
int rxPin = 3;
int txPin = 5;
int RST_PIN = 9;
int SS_PIN = 10;
int CLK_PIN = 6;
int DAT_PIN = 7;
int PST_PIN = 4;
int buzzerPin = 2;
int pirPin = 8;
int hareket;
int tarih;
int saat;
String ip = "";
MFRC522 rfid(SS_PIN, RST_PIN);
byte ID[4] = {47, 219, 106, 81};
byte okunandeger[4];
virtuabotixRTC myRTC(CLK_PIN, DAT_PIN, RST_PIN);
SoftwareSerial esp(rxPin, txPin);
void setup() {
pinMode(pirPin, INPUT);
pinMode(buzzerPin, OUTPUT);
myRTC.setDS1302Time(00, 57, 22, 7, 23, 1, 2022);
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
Serial.println("Started");
esp.begin(115200);
esp.println("AT");
Serial.println("AT Yollandı");
while (!esp.find("OK")) {
esp.println("AT");
Serial.println("ESP8266 Bulunamadı.");
}
Serial.println("OK Komutu Alındı");
esp.println("AT+CWMODE=1");
while (!esp.find("OK")) {
esp.println("AT+CWMODE=1");
Serial.println("Ayar Yapılıyor....");
}
Serial.println("Client olarak ayarlandı");
Serial.println("Aga Baglaniliyor...");
esp.println("AT+CWJAP=\"" + agAdi + "\",\"" + agSifresi + "\"");
while (!esp.find("OK"))
;
Serial.println("Aga Baglandi.");
delay(1000);
}
void loop() {
saatModulu();
rfidGiris();
byte okunankart[4] = rfid.uid.uidByte[];
int saat = String(myRTC.hours + ":" + myRTC.minutes + ":" + myRTC.seconds);
int tarih = String(myRTC.dayofmonth + ":" + myRTC.month + ":" + myRTC.year);
espFonk();
rfidCikis();
okunankart = rfid.uid.uidByte[];
int saat = String(myRTC.hours + ":" + myRTC.minutes + ":" + myRTC.seconds);
int tarih = String(myRTC.dayofmonth + ":" + myRTC.month + ":" + myRTC.year);
espFonk();
}
void espFonk() {
esp.println("AT+CIPSTART=\"TCP\",\"" + ip + "\",80");
if (esp.find("Error")) {
Serial.println("AT+CIPSTART Error");
}
String veri = "GET https://api.thingspeak.com/update?api_key=";
veri += "&field1=";
veri += String(okunankart);
veri += "&field2=";
veri += String(saat);
veri += "&field3=";
veri += String(tarih);
veri += "\r\n\r\n";
esp.print("AT+CIPSEND=");
esp.println(veri.length() + 2);
delay(2000);
if (esp.find(">")) {
esp.print(veri);
Serial.println(veri);
Serial.println("Veri gonderildi.");
delay(1000);
}
Serial.println("Baglantı Kapatildi.");
esp.println("AT+CIPCLOSE");
delay(1000);
}
void rfidGiris() {
if (!rfid.PICC_IsNewCardPresent()) return;
if (!rfid.PICC_ReadCardSerial()) return;
if (rfid.uid.uidByte[0] == ID[0] && rfid.uid.uidByte[1] == ID[1] &&
rfid.uid.uidByte[2] == ID[2] && rfid.uid.uidByte[3] == ID[3]) {
Serial.println("Güvenlik Sistemi Aktif!");
ekranaYazdir();
hareketSensor();
}
else {
Serial.print("Yetkisiz Kart");
ekranaYazdir();
melodi(500);
delay(500);
melodi(500);
}
rfid.PICC_HaltA();
}
void ekranaYazdir() {
Serial.print("ID Numarası : ");
for (int sayac = 0; sayac < 4; sayac++) {
Serial.print(rfid.uid.uidByte[sayac]);
Serial.print(" ");
}
}
void saatModulu() {
myRTC.updateTime();
Serial.print("Tarih / Saat: ");
Serial.print(myRTC.dayofmonth);
Serial.print("/");
Serial.print(myRTC.month);
Serial.print("/");
Serial.print(myRTC.year);
Serial.print(" ");
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
Serial.print(":");
Serial.print(myRTC.seconds);
delay(1000);
}
void hareketSensor() {
hareket = digitalRead(pirPin);
if (Hareket == HIGH) {
melodi(5000);
}
}
int melodi(int dly) {
tone(buzzerPin, 832);
delay(dly);
noTone(buzzerPin);
delay(dly);
}
void rfidCikis() {
if (!rfid.PICC_IsNewCardPresent()) return;
if (!rfid.PICC_ReadCardSerial()) return;
if (rfid.uid.uidByte[0] == ID[0] && rfid.uid.uidByte[1] == ID[1] &&
rfid.uid.uidByte[2] == ID[2] && rfid.uid.uidByte[3] == ID[3]) {
Serial.println("Güvenlik Sistemi Deaktif!");
ekranaYazdir();
hareket = LOW;
}
else {
Serial.print("Yetkisiz Kart");
ekranaYazdir();
melodi(500);
delay(500);
melodi(500);
}
rfid.PICC_HaltA();
}
This is error:
main.ino:166:8: note: suggested alternative: 'hareket'
exit status 1
expected primary-expression before ']' token
And Arduino IDE lighting
okunankart = rfid.uid.uidByte[];
For starters arrays do not have the assignment operator
okunankart = rfid.uid.uidByte[];
and in any case the expression with empty brackets is wrong.
The initializer in this declaration
byte okunankart[4] = rfid.uid.uidByte[];
is also wrong.
You need to copy elements from one array in another array for example using the standard algorithm std::copy or the C function memcpy.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to write a c++ program that assembles MIPS instructions. While debugging, it keeps throwing an error at line 74 of my main:
myassembler.add(lexed[i].labels[0], lexed[i].name, tokens, i);
my main is here:
#include <fstream>
#include <iostream>
#include <iomanip>
#include <memory>
#include <stdexcept>
#include <string>
#include <sstream>
#include <vector>
#include "exceptions.h"
#include "lexer.h"
#include "util.h"
#include "assembler.h"
std::string read_file(const std::string& name) {
std::ifstream file(name);
if (!file.is_open()) {
std::string error = "Could not open file: ";
error += name;
throw std::runtime_error(error);
}
std::stringstream stream;
stream << file.rdbuf();
return std::move(stream.str());
}
int main(int argc, char** argv) {
// Adjusting -- argv[0] is always filename.
--argc;
++argv;
if (argc == 0) {
std::cerr << "Need a file" << std::endl;
return 1;
}
assembler myassembler;
for (int i = 0; i < argc; ++i) {
std::string asmName(argv[i]);
if (!util::ends_with_subseq(asmName, std::string(".asm"))) {
std::cerr << "Need a valid file name (that ends in .asm)" << std::endl;
std::cerr << "(Bad name: " << asmName << ")" << std::endl;
return 1;
}
// 4 is len(".asm")
auto length = asmName.size() - string_length(".asm");
std::string baseName(asmName.begin(), asmName.begin() + length);
std::string objName = baseName + ".obj";
try {
auto text = read_file(asmName);
try {
auto lexed = lexer::analyze(text); // Parses the entire file and returns a vector of instructions
for (int i =0; i < (int)lexed.size(); i++){
if(lexed[i].labels.size() > 0) // Checking if there is a label in the current instruction
std::cout << "label = " << lexed[i].labels[0] << "\n"; // Prints the label
std::cout<< "instruction name = " << lexed[i].name<< "\n"; // Prints the name of instruction
std::cout << "tokens = ";
std::vector<lexer::token> tokens = lexed[i].args;
for(int j=0; j < (int)tokens.size(); j++){ // Prints all the tokens of this instruction like $t1, $t2, $t3
if (tokens[j].type == lexer::token::Integer)
std::cout << tokens[j].integer() << " ";
else
std::cout << tokens[j].string() << " ";
}
myassembler.add(lexed[i].labels[0], lexed[i].name, tokens, i);
myassembler.p();
std::cout << "\n\n\n";
}
} catch(const bad_asm& e) {
std::stringstream error;
error << "Cannot assemble the assembly code at line " << e.line;
throw std::runtime_error(error.str());
} catch(const bad_label& e) {
std::stringstream error;
error << "Undefined label " << e.what() << " at line " << e.line;
throw std::runtime_error(error.str());
}
} catch (const std::runtime_error& err) {
std::cout << err.what() << std::endl;
return 1;
}
}
/*getchar();*/
return 0;
}
assembler.h:
#include "lexer.h"
#include <fstream>
#include <vector>
#include <string>
struct symbol
{
std::string label = "";
int slinenum;
};
struct relocation
{
std::string instruct = "";
std::string label = "";
int rlinenum;
int rt = 0;
int rs = 0;
};
struct opcode
{
std::string instruct = "";
int opc = 0;
bool isloadstore = false;
int extType = 0;
bool isbranch = false;
};
struct function
{
std::string instruct = "";
int funct = 0;
bool isjr = false;
bool isshift = false;
};
struct regs
{
std::string name;
int num;
};
enum instrtype
{
R, I, neither
};
class assembler
{
public:
assembler();
void oinit(void);
void finit(void);
void rinit(void);
void printToFile(std::fstream &file);
void savesymb(std::string label, int line);
void saverel(std::string instr, std::string label, int line, int rt, int rs);
std::vector<int> formatr(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line);
int formatr(std::string instr, lexer::token toke, int line);
std::vector<int> formati(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line);
std::vector<int> formati(std::string instr, lexer::token toke1, lexer::token toke2, int line);
int findnum(std::string regname);
void add(std::string label, std::string instr, const std::vector<lexer::token> &tokens, int linen);
void secAdd(void);
int rassemble(std::string instr, int rd, int rs, int rt, int shamt);
int iassemble(std::string instr, int rt, int rs, int imm);
void p();
private:
std::vector<int> results;
std::vector<symbol> symbtable;
std::vector<relocation> reloctable;
std::vector<opcode> ops;
std::vector<function> functions;
std::vector<regs> registers;
instrtype type = neither;
};
and assembler.cpp:
// ECE 2500
// Project 1: myAssembler
// assembler.cpp
// Sheila Zhu
#include "lexer.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "assembler.h"
assembler::assembler()
{
oinit();
finit();
rinit();
}
void assembler::oinit()
{
opcode myop;
myop.instruct = "addi";
myop.opc = 8;
myop.extType = 1;
ops.push_back(myop);
// more of the same
}
void assembler::finit()
{
function myfunc;
myfunc.instruct = "add";
myfunc.funct = 32;
functions.push_back(myfunc);
// more of the same
}
void assembler::rinit()
{
regs myreg;
myreg.name = "$zero";
myreg.num = 0;
registers.push_back(myreg);
//more of the same
}
void assembler::printToFile(std::fstream &file)
{
for (int i = 0; i < (int)results.size(); i++)
file << results.at(i) << std::endl;
}
void assembler::savesymb(std::string label, int line)
{
symbol symb;
symb.label = label;
symb.slinenum = line * 4;
symbtable.push_back(symb);
}
void assembler::saverel(std::string instr, std::string label, int line, int rt, int rs)
{
relocation re;
re.instruct = instr;
re.label = label;
re.rlinenum = line;
re.rt = rt;
re.rs = rs;
}
int assembler::findnum(std::string regname)
{
for (int i = 0; i < (int)registers.size(); i++)
{
if (regname == registers.at(i).name)
return registers.at(i).num;
}
return -1;
}
std::vector<int> assembler::formatr(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line)
{
int rd = 0, rs = 0, rt = 0, shamt = 0;
std::vector<int> x;
function currf;
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
currf = functions.at(i);
}
try
{
if (currf.isshift)
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rd = findnum(toke1.string());
if (rd == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
{
shamt = toke3.integer();
if (shamt < 0)
throw 3;
}
else
throw 1;
}
else
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rd = findnum(toke1.string());
if (rd == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke3.string());
if (rt == -1)
throw 2;
}
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else if (e == 2)
std::cerr << "Invalid register name in line " << line << std::endl;
else
std::cerr << "Shift amount cannot be negative in line " << line << std::endl;
}
x.push_back(rd);
x.push_back(rs);
x.push_back(rt);
x.push_back(shamt);
return x;
}
int assembler::formatr(std::string instr, lexer::token toke, int line)
{
int rs = 0;
try
{
if (toke.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke.string());
if (rs == -1)
throw 2;
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
return rs;
}
std::vector<int> assembler::formati(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line)
{
int rt = 0, rs = 0, imm = 0;
std::vector<int> x;
opcode currop;
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
currop = ops.at(i);
}
try
{
if (currop.isbranch)
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
imm = toke3.integer();
else
saverel(instr, toke3.string(), line, rt, rs);
}
else if (currop.isloadstore)
{
if ((instr == "lbu") || (instr == "sb"))
{
if (toke2.type == lexer::token::String)
throw 1;
else
{
if (toke2.integer() < 0)
imm = (0xFFFF << 16) + (0xFF << 8) + toke2.integer();
else
imm = toke2.integer();
}
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
}
else
{
if (toke2.type == lexer::token::String)
throw 1;
else
{
if (toke2.integer() < 0)
imm = (0xFFFF << 16) + toke2.integer();
else
imm = toke2.integer();
}
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
}
}
else
{
if ((instr == "andi") || (instr == "ori"))
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
imm = toke3.integer();
else
throw 1;
}
else
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
{
if (toke3.integer() < 0)
imm = (0xFFFF << 16) + toke2.integer();
else
imm = toke3.integer();
}
else
throw 1;
}
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
x.push_back(rt);
x.push_back(rs);
x.push_back(imm);
return x;
}
std::vector<int> assembler::formati(std::string instr, lexer::token toke1, lexer::token toke2, int line)
{
int rt = 0, imm = 0;
std::vector<int> rval;
try
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::String)
throw 1;
else
imm = toke2.integer();
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
rval.push_back(rt);
rval.push_back(imm);
return rval;
}
void assembler::add(std::string label, std::string instr, const std::vector<lexer::token> &token, int linen)
{
int assembled = 0, rd = 0, rt = 0;
std::vector<int> argh;
int arg;
if (label.length() > 0)
savesymb(label, linen);
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
type = R;
}
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
type = I;
}
if (type == R)
{
try
{
if (instr == "jr")
{
if ((int)token.size() == 1)
{
arg = formatr(instr, token.at(0), linen);
assembled = rassemble(instr, rd, arg, rt, 0);
}
else
throw 1;
}
else
{
if ((int)token.size() == 3)
{
argh = formatr(instr, token.at(0), token.at(2), token.at(3), linen);
assembled = rassemble(instr, argh[0], argh[1], argh[2], argh[3]);
}
else
throw 1;
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong number of arguments at line " << linen << std::endl;
}
}
else if (type == I)
{
try
{
if (instr == "lui")
{
if ((int)token.size() == 2)
{
argh = formati(instr, token.at(0), token.at(1), linen);
assembled = iassemble(instr, argh[0], 0, argh[1]);
}
else
throw 1;
}
else
{
if ((int)token.size() == 3)
{
argh = formati(instr, token.at(0), token.at(1), token.at(2), linen);
assembled = iassemble(instr, argh[0], argh[1], argh[2]);
}
else
throw 1;
}
}
catch (int e)
{
if (e == 1)
std::cout << "Wrong number of arguments at line " << linen << std::endl;
}
}
else
std::cerr << "Instruction not recognized at line " << linen << std::endl;
results.push_back(assembled);
}
void assembler::secAdd(void)
{
std::vector<int>::iterator iter = results.begin();
for (int i = 0; i < (int)reloctable.size(); i++)
{
for (unsigned int j = 0; j < symbtable.size(); j++)
{
if (reloctable.at(i).label == symbtable.at(j).label)
{
int assembled = 0;
iter += (reloctable.at(i).rlinenum / 4);
for (unsigned int k = 0; k < ops.size(); k++)
{
if (reloctable.at(i).instruct == ops.at(k).instruct)
type = I;
}
if (type == I)
assembled = iassemble(reloctable.at(i).instruct, reloctable.at(i).rt, reloctable.at(i).rs, symbtable.at(i).slinenum);
else
std::cerr << "Instruction not recognized at line " << reloctable.at(i).rlinenum << std::endl;
results.erase(iter);
results.insert(iter, assembled);
}
}
}
}
int assembler::rassemble(std::string instr, int rd, int rs, int rt, int shamt)
{
int func = 0;
int code = 0;
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
{
func = functions.at(i).funct;
break;
}
else
{
if (i == (functions.size() - 1))
return -1;
}
}
code = (rs << 21) + (rt << 16) + (rd << 11) + (shamt << 6) + func;
return code;
}
int assembler::iassemble(std::string instr, int rt, int rs, int imm)
{
int op = 0;
int code = 0;
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
{
op = ops.at(i).opc;
break;
}
else
{
if (i == (ops.size() - 1))
return -1;
}
}
code = (op << 26) + (rs << 21) + (rt << 16) + imm;
return code;
}
void assembler::p()
{
for (int i = 0; i < (int)results.size(); i++)
std::cout << results.at(i) << " ";
std::cout << std::endl;
}
When debugging, the tokens parameter triggers the error, and the this pointer in the vector code shows that the vector size changes to 0 at these lines:
#if _ITERATOR_DEBUG_LEVEL == 2
if (size() <= _Pos)
What exactly is happening?
Sorry if my formatting is bad/wrong, etc., and please let me know if I should make any edits/provide more code.
Thanks in advance.
The error is caused by accessing by index vector element that does not exist.
In you case lexed[i] should be valid. So, the only possible issue may be with empty labels vector. Validate this vector before accessing its elements, for example
myassembler.add(lexed[i].labels.empty() ? "" : lexed[i].labels[0],
lexed[i].name, tokens, i);
Actually there is one more bug for very large lexed arrays when integer index may overflow. You should not cast result of .size() to int. Instead proper type should be used for i:
for (size_t i = 0; i < lexed.size(); i++)
I have an issue where my Arduino program hangs for no reason. I run my program, and at some undetermined point, the Serial Monitor stops printing output. Here's what I've tested so far:
In my "com.init_drone()" method, I've commented everything out except for the last line, which signals that the method returned. When I do this, my program hangs somewhere else but still it doesn't get to the infinite while loop.
I've been outputting memory usage, and I'm getting numbers no lower than 450 -- this tells me that I'm not using an absurd amount of memory.
I've tried removing the Timer1 instantiation, interrupt attach/detach, bu that has had no effect on the program.
My .ino file(and Command) is located here for anyone that wants a fuller picture and doesn't want to scroll through all this code I'm going to post below.
Here's my log output so far. Notice the truncation!:
AT&F
AT+NMAC=00:1d:c9:10:39:6f
AT+WM=0
AT+NDHCP=1
AT+WA=ardrone_279440
AT+NCUDP=192.168.1.1,5556
S0AT*CONFIG=1,"general:navdata_demo","TRUE"
EAT*CONFIG=1,"general:navdata_demo","TRUE"
638
S0AT*CONFIG=2,"control:altitude_max","2000"
EAT*CONFIG=2,"control:altitude_max","2000"
638
S0AT*CONFIG=3,"control:euler_angle_max","0.35"
EAT*CONFIG=3,"control:euler_angle_max","0.35"
586
S0AT*CONFIG=4,"control:outdoor","FALSE"
EAT*CONFIG=4,"control:outdoor","FALSE"
635
S0AT*CONFIG=5,"control:flight_without_shell","FALSE"
EAT*CONFIG=5,"control:flight_without_shell","FALSE"
574
S0AT*CTRL=6,4,0
EAT*CTRL=6,4,0
629
S0AT*CTRL=7,0,0
EAT*CTRL=7,0,0
629
S0AT*CTRL=8,4,0
EAT*CTRL=8,4,0
629
S0AT*COMWDG=9
EAT*COMWDG=9
629
S0AT*COMWDG=10
EAT*COMWDG=10
629
S0AT*COMWDG=11
EAT*COMWDG=11
629
S0AT*COMWDG=12
EAT*COMWDG=12
629
S0AT*COMWDG=13
EAT*COMWDG=13
629
S0AT*FTRIM=14
EAT*FTRIM=14
629
Here is my .ino file:
#include "Command.h"
#include "Streaming.h"
int debug = 1;
extern ring_buffer rx_buf;
extern resultint_ resultint;
Command com;
int sequenceNumber = 1;
String atcmd = "";
#include "TimerOne.h"
#define LEDpin 13
void setup()
{
PCsrl.begin(9600);
com.start_wifi_connection();
com.drone_is_init = com.init_drone();
Timer1.initialize(COMWDG_INTERVAL_USEC);
Timer1.attachInterrupt(watchdog_timer);
}
void watchdog_timer() {
com.sendwifi(com.makeComwdg());
}
void loop()
{
if (com.drone_is_init == 0) {
if (debug) {
// never use three ! together in arduino code
PCsrl.println("Drone wasn't initlized before loop() was called. Initalizing now.\r\n");
}
} else {
com.drone_takeoff();
com.drone_takeoff();
com.sendwifi(com.makePcmd(1,0,0,0,0));
com.sendwifi(com.makePcmd(1,0,0,0,0));
delay(5000);
com.moveForward(1);
com.moveRotate(180);
com.moveForward(1);
com.moveRotate(180);
delay(500);
com.drone_landing();
com.drone_landing();
delay(500);
//end of program
Timer1.detachInterrupt();
PCsrl.println("Program finished");
while (1){};
}
}
And my Command.cpp
#ifndef GAINSPAN
#define GAINSPAN
#include "Command.h"
extern int sequenceNumber;
extern int debug;
ring_buffer rx_buf= {{0}, 0, 0};
resultint_ resultint;
Command::Command()
{
at = "";
command = "";
s2ip_running = 0;
drone_is_init = 0;
drone_is_hover = 0;
emergency = 0;
}
void Command::sendwifi(String s) {
WIFIsrl.write(27); //esc
WIFIsrl.print("S0"); //choose connection CID 0
WIFIsrl.print(s);
WIFIsrl.write(27);
WIFIsrl.print("E");
if(debug) PCsrl.println(s);
WIFIsrl.println(memoryTest());
}
int Command::start_wifi_connection()
{
WIFIsrl.begin(9600);
WIFIsrl.println("");
WIFIsrl.println("AT&F");
//WIFIsrl.println("ATE0"); //turn off echo
WIFIsrl.print("AT+NMAC=00:1d:c9:10:39:6f\r"); //set MAC address
WIFIsrl.println("AT+WM=0");
WIFIsrl.println("AT+NDHCP=1");
/* drone's network profile, change if needed*/
WIFIsrl.println("AT+WA=ardrone_279440");
WIFIsrl.println("AT+NCUDP=192.168.1.1,5556");
readARsrl();
delay(3000); //need 3 seconds for connection to establish
return 0;
}
String Command::makeComwdg()
{
at = "AT*COMWDG=";
command = at + getSequenceNumber() + "\r\n";
return command;
}
void Command::sendComwdg_t(int msec)
{
for (int i = 0; i < msec; i+=20) {
sendwifi(makeComwdg());
delay(20);
}
}
void Command::sendFtrim()
{
at = "AT*FTRIM=";
command = at + getSequenceNumber() + "\r\n";
sendwifi(command);
}
void Command::sendConfig(String option, String value)
{
at = "AT*CONFIG=";
command = at + getSequenceNumber() + ",\"" + option + "\",\"" + value + "\"\r\n";
sendwifi(command);
}
void Command::sendRef(flying_status fs)
{
at = "AT*REF=";
if(fs == TAKEOFF){
command = at + getSequenceNumber() + ",290718208\r\n"; //takeoff
}
else if(fs == LANDING){
command = at + getSequenceNumber() + ",290717696\r\n"; //landing
} else if (fs == EMERGENCY_TOGGLE){
command = at + getSequenceNumber() + ",290717952\r\n"; //landing
}
// emergency -> 290717952
sendwifi(command);
}
void Command::send_control_commands(){
at = "AT*CTRL=";
sendwifi(at+getSequenceNumber()+",4,0\r\n");
sendwifi(at+getSequenceNumber()+",0,0\r\n");
sendwifi(at+getSequenceNumber()+",4,0\r\n");
}
void Command::drone_emergency_reset()
{
at = "AT*REF=";
command = at + getSequenceNumber() + ",290717952\r\n";
sendwifi(command);
}
/** Movement functions **/
int Command::moveForward(float distanceInMeters)
{
float i = 0;
String moveForward = makePcmd(1, 0, -.855, 0, 0);
delay(1000*distanceInMeters);
sendPcmd(moveForward);
return 1;
}
int Command::moveRotate(float yawInDegrees)
{
int i = 0;
while (i < yawInDegrees) {
String stayRotate = makePcmd(1, 0, 0, 0, 0.17);
sendPcmd(stayRotate);
delay(150);
i += 8;
}
return 1;
}
String Command::makePcmd(int enable, float roll, float pitch, float gaz, float yaw)
{
at = "AT*PCMD=";
command = at + getSequenceNumber() + "," + enable + "," + fl2int(roll) + "," + fl2int(pitch) + "," + fl2int(gaz) + "," + fl2int(yaw) + "\r";
return command;
}
void Command::sendPcmd(String command)
{
previousCommand = command;
sendwifi(command);
}
void Command::sendPcmd(int enable, float roll, float pitch, float gaz, float yaw)
{
at = "AT*PCMD=";
command = at + getSequenceNumber() + "," + enable + "," + fl2int(roll) + "," + fl2int(pitch) + "," + fl2int(gaz) + "," + fl2int(yaw) + "\r";
sendwifi(command);
}
String Command::makeAnim(anim_mayday_t anim, int time)
{
at = "AT*ANIM=";
command = at + getSequenceNumber() + "," + anim + "," + time + "\r\n";
return command;
}
void Command::doLEDAnim(int animseq, int duration)
{
PCsrl << "calling LEDAnim" << endl;
at = "AT*LED=";
command = at + getSequenceNumber() + "," + animseq + ",1073741824," + duration + "\r\n";
sendwifi(command);
}
int Command::start_s2ip()
{
char temp;
//delay(20000); //wait for drone to start
readARsrl();
if (debug) {
PCsrl << "trying to start s2ip" << endl;
}
ARsrl.print("\r\n");
delay(500);
ARsrl.print("\r\n");
delay(500);
ARsrl << "cd ~" << endl;
if (debug) {
readARsrl();
}
delay(500);
ARsrl << "cd data/video/apps/" << endl;
delay(500);
ARsrl << "./s2ip.arm" << endl;
while ((int) temp != 2) {
temp = ARsrl.read();
if (temp == 2) {
PCsrl << "s2ip is running" << endl;
ARsrl << "bullshit\r\n"; //to fix a delay bug
break;
}
//PCsrl << "s2ip not running" << endl;
}
if (debug) {
while (ARsrl.available()) {
PCsrl.write(ARsrl.read());
}
}
return 1;
}
void Command::quit_s2ip()
{
ARsrl.println("EXIT");
while (ARsrl.available()) {
PCsrl.write(ARsrl.read());
}
}
int Command::init_drone()
{
sendConfig("general:navdata_demo","TRUE");
sendConfig("control:altitude_max","2000");
sendConfig("control:euler_angle_max","0.35");
sendConfig("control:outdoor","FALSE");
sendConfig("control:flight_without_shell","FALSE");
send_control_commands();
sendComwdg_t(90);
sendFtrim();
drone_emergency_reset(); //clear emergency flag
return 1;
}
int Command::drone_takeoff()
{
sendRef(TAKEOFF);
int i = 0;
return 1;
}
int Command::drone_hover(int msec)
{
int i = 0;
while (i < msec) {
sendwifi(makePcmd(1, 0, 0, 0, 0));
delay(100);
i += 100;
}
return 1;
}
int Command::drone_landing()
{
sendRef(LANDING);
return 1;
}
int Command::drone_move_up(int centimeter)
{
int i = 0;
while (i < centimeter) {
ARsrl << makePcmd(1, 0, 0, 0.6, 0);
delay(100);
i += 10;
}
return 1;
}
int Command::drone_move_down(int centimeter)
{
int i = 0;
while (i < centimeter) {
sendwifi(makePcmd(1, 0, 0, -0.5, 0));
delay(100);
i += 10;
}
return 1;
}
long Command::fl2int(float value)
{
resultint.i = 0;
if (value < -1 || value > 1) {
resultint.f = 1;
} else {
resultint.f=value;
}
return resultint.i;
}
void Command::readARsrl()
{
while (ARsrl.available()) {
if (debug) {
PCsrl.write(ARsrl.read());
}
}
}
//Memory test code from : http://www.faludi.com/2007/04/18/arduino-available-memory-test/
int Command::memoryTest() {
int byteCounter = 0; // initialize a counter
byte *byteArray; // create a pointer to a byte array
// More on pointers here: http://en.wikipedia.org/wiki/Pointer#C_pointers
// use the malloc function to repeatedly attempt
// allocating a certain number of bytes to memory
// More on malloc here: http://en.wikipedia.org/wiki/Malloc
while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) {
byteCounter++; // if allocation was successful, then up the count for the next try
free(byteArray); // free memory after allocating it
}
free(byteArray); // also free memory after the function finishes
return byteCounter; // send back the highest number of bytes successfully allocated
}
int Command::getSequenceNumber(){
return sequenceNumber++;
}
// Volatile, since it is modified in an ISR.
volatile boolean inService = false;
void SrlRead()
{
if (inService) {
PCsrl.println("timer kicked too fast");
return;
}
interrupts();
inService = true;
while(ARsrl.available()) {
unsigned char k = ARsrl.read();
store_char(k, &rx_buf);
}
inService = false;
}
void read_rx_buf()
{
while (rx_buf.tail != rx_buf.head) {
if (debug) {
PCsrl.write(rx_buf.buffer[rx_buf.tail]);
}
rx_buf.tail = (unsigned int) (rx_buf.tail+ 1) % SERIAL_BUFFER_SIZE;
}
}
inline void store_char(unsigned char c, ring_buffer *buffer)
{
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != buffer->tail) {
buffer->buffer[buffer->head] = c;
buffer->head = i;
}
else {
Serial.println("ring buffer is too small");
}
}
#endif
I know it sounds weird but, sometimes this happens when arduino is not getting enough power supply. Try connecting the arduino to a power source different from USB.
As soon as I started to put things in prog memory my program started to clear up it's hiccups. It seems it was a memory issue.
I had the same problem, but the issue was with Timer1.initialize(). Try this:
com.drone_is_init = com.init_drone();
Serial.println("One");
Serial.println("Two");
Serial.println("Three");
Timer1.initialize(COMWDG_INTERVAL_USEC);
Timer1.attachInterrupt(watchdog_timer);
Open serial monitor and see... it will show until "Two", and then Arduino will hang.
The issue was I calling some functions of the LiquidCrystal_I2C library, that need interrupt routines. Check if your timer ISR is using some interrupts. If so, you should move this code to another place in your project.
I have noted that the cascades trained with the program opencv_traincascade does not run with the current version of opencv_performance. I've tried to convert the old performance cpp file to load the new types of cascades, but without success. The code is here:
#include "cv.h"
#include "highgui.h"
#include <cstdio>
#include <cmath>
#include <ctime>
#include <math.h>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX 512
#endif /* PATH_MAX */
/*typedef struct HidCascade {
int size;
int count;
} HidCascade;
*/
typedef struct ObjectPos {
float x;
float y;
float width;
int found; /* for reference */
int neghbors;
} ObjectPos;
using namespace std;
using namespace cv;
int main(int argc, char* argv[]) {
int i, j;
char* classifierdir = NULL;
//char* samplesdir = NULL;
int saveDetected = 1;
double scale_factor = 1.1;
float maxSizeDiff = 1.5F;
float maxPosDiff = 1.1F;
/* number of stages. if <=0 all stages are used */
//int nos = -1, nos0;
int width = 25;
int height = 15;
int rocsize;
FILE* info;
FILE* resultados;
char* infoname;
char fullname[PATH_MAX];
//char detfilename[PATH_MAX];
char* filename;
//char detname[] = "det-";
CascadeClassifier cascade;
double totaltime;
if (!(resultados = fopen("resultados.txt", "w"))) {
printf("Cannot create results file.\n");
exit(-1);
}
infoname = (char*) "";
rocsize = 20;
if (argc == 1) {
printf("Usage: %s\n -data <classifier_directory_name>\n"
" -info <collection_file_name>\n"
" [-maxSizeDiff <max_size_difference = %f>]\n"
" [-maxPosDiff <max_position_difference = %f>]\n"
" [-sf <scale_factor = %f>]\n"
" [-ni]\n"
" [-rs <roc_size = %d>]\n"
" [-w <sample_width = %d>]\n"
" [-h <sample_height = %d>]\n", argv[0], maxSizeDiff,
maxPosDiff, scale_factor, rocsize, width, height);
return 0;
}
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-data")) {
classifierdir = argv[++i];
} else if (!strcmp(argv[i], "-info")) {
infoname = argv[++i];
} else if (!strcmp(argv[i], "-maxSizeDiff")) {
maxSizeDiff = (float) atof(argv[++i]);
} else if (!strcmp(argv[i], "-maxPosDiff")) {
maxPosDiff = (float) atof(argv[++i]);
} else if (!strcmp(argv[i], "-sf")) {
scale_factor = atof(argv[++i]);
} else if (!strcmp(argv[i], "-ni")) {
saveDetected = 0;
} else if (!strcmp(argv[i], "-rs")) {
rocsize = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-w")) {
width = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-h")) {
height = atoi(argv[++i]);
}
}
if (!cascade.load(classifierdir)) {
printf("Unable to load classifier from %s\n", classifierdir);
return 1;
}
strcpy(fullname, infoname);
filename = strrchr(fullname, '\\');
if (filename == NULL) {
filename = strrchr(fullname, '/');
}
if (filename == NULL) {
filename = fullname;
} else {
filename++;
}
info = fopen(infoname, "r");
totaltime = 0.0;
if (info != NULL) {
int x, y, width, height;
Mat img;
int hits, missed, falseAlarms;
int totalHits, totalMissed, totalFalseAlarms;
int found;
float distance;
int refcount;
ObjectPos* ref;
int detcount;
ObjectPos* det;
int error = 0;
int* pos;
int* neg;
pos = (int*) cvAlloc(rocsize * sizeof(*pos));
neg = (int*) cvAlloc(rocsize * sizeof(*neg));
for (i = 0; i < rocsize; i++) {
pos[i] = neg[i] = 0;
}
printf("+================================+======+======+======+\n");
printf("| File Name | Hits |Missed| False|\n");
printf("+================================+======+======+======+\n");
fprintf(resultados,
"+================================+======+======+======+\n");
fprintf(resultados,
"| File Name | Hits |Missed| False|\n");
fprintf(resultados,
"+================================+======+======+======+\n");
//fprintf (resultados, "%d\n",framesCnt);
totalHits = totalMissed = totalFalseAlarms = 0;
while (!feof(info)) {
fscanf(info, "%s %d", filename, &refcount);
img = imread(fullname);
if (!img.data) {
cout << "ow" << endl;
return -1;
}
ref = (ObjectPos*) cvAlloc(refcount * sizeof(*ref));
for (i = 0; i < refcount; i++) {
error = (fscanf(info, "%d %d %d %d", &x, &y, &width, &height)
!= 4);
if (error)
break;
ref[i].x = 0.5F * width + x;
ref[i].y = 0.5F * height + y;
ref[i].width = sqrt(0.5F * (width * width + height * height));
ref[i].found = 0;
ref[i].neghbors = 0; //in the new cascade, where to get the neighbors?
}
vector<Rect> obj_detectados;
Rect retang;
if (!error) {
totaltime -= time(0);
cascade.detectMultiScale(img, obj_detectados, scale_factor, 4, 0
//|CV_HAAR_FIND_BIGGEST_OBJECT
// |CV_HAAR_DO_ROUGH_SEARCH
| CV_HAAR_SCALE_IMAGE, Size(25, 15));
totaltime += time(0);
if (obj_detectados.size() == 0) {
detcount = 0;
} else {
detcount = obj_detectados.size();
}
det = (detcount > 0) ?
((ObjectPos*) cvAlloc(detcount * sizeof(*det))) : NULL;
hits = missed = falseAlarms = 0;
for (vector<Rect>::const_iterator r = obj_detectados.begin();
r != obj_detectados.end(); r++, i++) {
Point r1, r2;
r1.x = (r->x);
r1.y = (r->y);
r2.x = (r->x + r->width);
r2.y = (r->y + r->height);
retang.x = r1.x;
retang.y = r1.y;
retang.width = abs(r2.x - r1.x);
retang.height = abs(r2.y - r1.y);
if (saveDetected) {
rectangle(img, retang, Scalar(0, 0, 255), 3, CV_AA);
}
det[i].x = 0.5F*r->width + r->x;
det[i].y = 0.5F*r->height + r->y;
det[i].width = sqrt(0.5F * (r->width * r->width
+ r->height * r->height));
det[i].neghbors = 1; // i don't know if it will work...
// det[i].neghbors = r.neighbors; --- how to do it in the new version??
found = 0;
for (j = 0; j < refcount; j++) {
distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
(det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
//cout << distance << endl;
if( (distance < ref[j].width * maxPosDiff) &&
(det[i].width > ref[j].width / maxSizeDiff) &&
(det[i].width < ref[j].width * maxSizeDiff) )
{
ref[j].found = 1;
ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
found = 1;
}
}
if (!found) {
falseAlarms++;
neg[MIN(det[i].neghbors, rocsize - 1)]++;
//neg[MIN(0, rocsize - 1)]++;
}
}
//imshow("teste", img);
if (saveDetected) {
//strcpy(detfilename, detname);
//strcat(detfilename, filename);
//strcpy(filename, detfilename);
imwrite(fullname, img);
//cvvSaveImage(fullname, img);
}
for (j = 0; j < refcount; j++) {
if (ref[j].found) {
hits++;
//pos[MIN(0, rocsize - 1)]++;
pos[MIN(ref[j].neghbors, rocsize - 1)]++;
} else {
missed++;
}
}
totalHits += hits;
totalMissed += missed;
totalFalseAlarms += falseAlarms;
printf("|%32.64s|%6d|%6d|%6d|\n", filename, hits, missed,
falseAlarms);
//printf("+--------------------------------+------+------+------+\n");
fprintf(resultados, "|%32.64s|%6d|%6d|%6d|\n", filename, hits,
missed, falseAlarms);
//fprintf(resultados,
// "+--------------------------------+------+------+------+\n");
fflush(stdout);
if (det) {
cvFree( &det);
det = NULL;
}
} /* if( !error ) */
//char c = (char) waitKey(10);
// if (c == 27)
// exit(0);
cvFree( &ref);
}
fclose(info);
printf("|%32.32s|%6d|%6d|%6d|\n", "Total", totalHits, totalMissed,
totalFalseAlarms);
fprintf(resultados, "|%32.32s|%6d|%6d|%6d|\n", "Total", totalHits,
totalMissed, totalFalseAlarms);
printf("+================================+======+======+======+\n");
fprintf(resultados,
"+================================+======+======+======+\n");
//printf("Number of stages: %d\n", nos);
//printf("Number of weak classifiers: %d\n", numclassifiers[nos - 1]);
printf("Total time: %f\n", totaltime);
fprintf(resultados, "Total time: %f\n", totaltime);
/* print ROC to stdout */
for (i = rocsize - 1; i > 0; i--) {
pos[i - 1] += pos[i];
neg[i - 1] += neg[i];
}
//fprintf(stderr, "%d\n", nos);
for (i = 0; i < rocsize; i++) {
fprintf(stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
((float) pos[i]) / (totalHits + totalMissed),
((float) neg[i]) / (totalHits + totalMissed));
}
cvFree( &pos);
cvFree( &neg);
}
return 0;
}
My doubt is about the det[i].neghbors = r.neighbors; in the old performance.cpp. How I retrieve the neighbors in this new version?
Anyone could help me to convert opencv_performance to run the new cascades from opencv_traincascade?
Many thanks!