I am trying to simulate a sensor array in Castalia capable of using more than one sensor per node but when I run the simulation it takes the names of the sensors as one item and ends up displaying the sensor index and value of the sensor mentioned first. Please help!! how can I get it to detect more than one sensor per node
omnetpp.ini (valueReporting)
[General]
# ==========================================================
# Always include the main Castalia.ini file
# ==========================================================
include ../Parameters/Castalia.ini
sim-time-limit = 600s
SN.field_x = 100 # meters
SN.field_y = 100 # meters
SN.numNodes = 36
SN.deployment = "6x6"
SN.node[*].Communication.Radio.RadioParametersFile = "../Parameters/Radio/CC2420.txt"
SN.node[*].Communication.MACProtocolName = "TMAC"
SN.node[*].Communication.RoutingProtocolName = "MultipathRingsRouting"
#SN.node[*].Communication.Routing.collectTraceInfo = true
SN.node[*].ApplicationName = "ValueReporting"
SN.node[3].Application.isSink = true
# test 2 physical processes
SN.numPhysicalProcesses = 2
SN.physicalProcess[0].printDebugInfo = true
SN.physicalProcess[1].printDebugInfo = true
SN.physicalProcess[0].description = "Degrees Celsius"
SN.physicalProcess[1].description = "Blood Glucose"
SN.physicalProcess[0].inputType = 1
SN.physicalProcess[1].inputType = 1
#SN.physicalProcess[0].directNodeValueAssignment = "(0) 0:25 1:23 2:21 3:24 4:26"
#SN.physicalProcess[1].directNodeValueAssignment = "(0) 0:360 1:380 2:375 3:390 4:390"
SN.node[*].SensorManager.numSensingDevices = 2
SN.node[*].SensorManager.sensorTypes = "Temperature Bloodglucose"
SN.node[*].SensorManager.corrPhyProcess = "0 1"
In the SensorManager.ned file, I changed these lines as for the rest of the file everything is left as is
string sensorTypes = default ("Temperature,Bloodglucose");
// string array of comma-separated Names for the sensing devices
string corrPhyProcess = default ("0,1");
Now the temperature physical process files
TemperaturePhysicalProcess.ned
package physicalProcess.temperaturePhysicalProcess;
simple TemperaturePhysicalProcess like physicalProcess.iPhysicalProcess {
parameters:
bool collectTraceInfo = default (true);
double temperature = default (37); //normal body temperature is 37 degrees celcius
string description = default ("Degrees Celsius");
gates:
output toNode[];
input fromNode[];
}
TemperaturePhysicalProcess.h
#ifndef _TEMPERATUREPHYSICALPROCESS_H_
#define _TEMPERATUREPHYSICALPROCESS_H_
#define SIMTIME_STEP 0.01
#include "CastaliaModule.h"
#include "PhysicalProcessMessage_m.h"
using namespace std;
typedef struct {
simtime_t time;
double x;
double y;
} sourceSnapshot;
class TemperaturePhysicalProcess: public CastaliaModule {
private:
bool printDebugInfo;
int temperature;
const char *description;
protected:
virtual void initialize();
virtual void handleMessage(cMessage * msg);
virtual void finishSpecific();
};
#endif
TemperaturePhysicalProcess.cc
#include "TemperaturePhysicalProcess.h"
Define_Module(TemperaturePhysicalProcess);
void TemperaturePhysicalProcess::initialize()
{
temperature=37;
//Search for snapshots in castalia manual
}
void TemperaturePhysicalProcess::handleMessage(cMessage * msg)
{
if (msg->getKind() != PHYSICAL_PROCESS_SAMPLING)
{
opp_error("Physical Process received message other than PHYSICAL_PROCESS_SAMPLING");
}
PhysicalProcessMessage *receivedMsg = check_and_cast < PhysicalProcessMessage * >(msg);
int nodeIndex = receivedMsg->getSrcID();
// Send reply back to the node who made the request
receivedMsg->setValue(temperature);
send(receivedMsg, "toNode", nodeIndex);
}
void TemperaturePhysicalProcess::finishSpecific() {}
Now we'll go to the Blood Glucose physical process
BloodGlucoseLevelPhysicalProcess.ned
package physicalProcess.bloodGlucoseLevelPhysicalProcess;
simple BloodGlucoseLevelPhysicalProcess like physicalProcess.iPhysicalProcess {
parameters:
bool collectTraceInfo = default (false);
int averagebloodglucose = default (100); // the amount is in mg per dL
int age = default (20);
string description = default ("Blood Glucose");
gates:
output toNode[];
input fromNode[];
}
BloodGlucoseLevelPhysicalProcess.h
#ifndef _BLOOODGLUCOSELEVELPHYSICALPROCESS_H_
#define _BLOOODGLUCOSELEVELPHYSICALPROCESS_H_
#define SIMTIME_STEP 0.01
#include "CastaliaModule.h"
#include "PhysicalProcessMessage_m.h"
using namespace std;
typedef struct {
simtime_t time;
double x;
double y;
} sourceSnapshot;
class BloodGlucoseLevelPhysicalProcess: public CastaliaModule {
private:
bool printDebugInfo;
int averagebloodglucose;
double A1c;
const char *description;
protected:
virtual void initialize();
virtual void handleMessage(cMessage * msg);
virtual void finishSpecific();
};
#endif
BloodGlucoseLevelLevelPhysicalProcess.cc
#include "BloodGlucoseLevelPhysicalProcess.h"
Define_Module(BloodGlucoseLevelPhysicalProcess);
void BloodGlucoseLevelPhysicalProcess::initialize()
{
averagebloodglucose = par("averagebloodglucose");
description = par("description").stringValue();
A1c = (46.7 + averagebloodglucose) / 28.7;
//Search for snapshots in castalia manual
}
void BloodGlucoseLevelPhysicalProcess::handleMessage(cMessage * msg)
{
if (msg->getKind() != PHYSICAL_PROCESS_SAMPLING)
opp_error("Physical Process received message other than PHYSICAL_PROCESS_SAMPLING");
PhysicalProcessMessage *receivedMsg = check_and_cast < PhysicalProcessMessage * >(msg);
int nodeIndex = receivedMsg->getSrcID();
//int sensorIndex = receivedMsg->getSensorIndex();
double returnValue;
// Send reply back to the node who made the request
//receivedMsg->setValue(returnValue);
receivedMsg->setValue(A1c);
send(receivedMsg, "toNode", nodeIndex);
}
void BloodGlucoseLevelPhysicalProcess::finishSpecific() {
}
Since I'm running the simulation using the ValueReporting application
ValueReporting.h
#define _VALUEREPORTING_H_
#include "VirtualApplication.h"
#include "ValueReportingPacket_m.h"
using namespace std;
enum ValueReportingTimers {
REQUEST_SAMPLE = 1,
SEND_DATA = 2,
};
class ValueReporting: public VirtualApplication {
private:
double maxSampleInterval;
double minSampleInterval;
int routingLevel;
double lastSensedValue;
int currSentSampleSN;
double randomBackoffIntervalFraction;
bool sentOnce;
int recipientId;
string recipientAddress;
protected:
void startup();
void fromNetworkLayer(ApplicationPacket *, const char *, double, double);
void handleSensorReading(SensorReadingMessage *);
void timerFiredCallback(int);
void requestSensorReading(const char *);
};
#endif // _VALUEREPORTING_APPLICATIONMODULE_H_
ValueReporting.cc
#include "ValueReporting.h"
#include <iostream> // std::cout
#include <iomanip>
#include <string> // std::string, std::to_string
#include <stdlib.h> /* atof */
#include <math.h>
#include<sstream>
#include <cstring>
#include <vector>
#include <array>
#include <string>
#include <algorithm>
Define_Module(ValueReporting);
void ValueReporting::startup()
{
maxSampleInterval = ((double)par("maxSampleInterval")) / 1000.0;
minSampleInterval = ((double)par("minSampleInterval")) / 1000.0;
currSentSampleSN = 0;
randomBackoffIntervalFraction = genk_dblrand(0);
sentOnce = false;
setTimer(REQUEST_SAMPLE, maxSampleInterval * randomBackoffIntervalFraction);
}
void ValueReporting::timerFiredCallback(int index)
{
switch (index) {
case REQUEST_SAMPLE:{
requestSensorReading("Temperature");
//requestSensorReading("Urine");
setTimer(REQUEST_SAMPLE, maxSampleInterval);
break;
}
}
}
void ValueReporting::fromNetworkLayer(ApplicationPacket * genericPacket,
const char *source, double rssi, double lqi)
{
ValueReportingDataPacket *rcvPacket = check_and_cast<ValueReportingDataPacket*>(genericPacket);
ValueReportData theData = rcvPacket->getExtraData();
trace() << "Sink received from: " << theData.nodeID << " \tvalue=" << rcvPacket->getData();
}
void ValueReporting::handleSensorReading(SensorReadingMessage * rcvReading)
{
int sensIndex = rcvReading->getSensorIndex();
string sensType(rcvReading->getSensorType());
double sensValue = rcvReading->getSensedValue();
double x_coor = mobilityModule->getLocation().x;
double y_coor = mobilityModule->getLocation().y;
string sensorindex = to_string(sensIndex);
string sensvalue = to_string(sensValue);
string xcoor = to_string(x_coor);
string ycoor = to_string(y_coor);
string sensorinfo= sensorindex + " " + sensvalue + " " + xcoor + " " + ycoor + " " + sensType;
trace() << sensorinfo;
ValueReportData tmpData;
tmpData.nodeID = (unsigned short)self;
tmpData.locX = mobilityModule->getLocation().x;
tmpData.locY = mobilityModule->getLocation().y;
ValueReportingDataPacket *packet2Net =
new ValueReportingDataPacket("Value reporting pck", APPLICATION_PACKET);
packet2Net->setExtraData(tmpData);
packet2Net->setData(sensValue);
packet2Net->setSequenceNumber(currSentSampleSN);
currSentSampleSN++;
toNetworkLayer(packet2Net, SINK_NETWORK_ADDRESS);
//toNetworkLayer(packet2Net, "6");
sentOnce = true;
}
void ValueReporting::requestSensorReading(const char * type){
SensorReadingMessage *reqMsg =
new SensorReadingMessage("App to Sensor Mgr: sample request", SENSOR_READING_MESSAGE);
if(type == "Temperature"){
reqMsg->setSensorType(type);
reqMsg->setSensorIndex(0);
}
if(type =="BloodGlucose"){
reqMsg->setSensorType(type);
reqMsg->setSensorIndex(1);
}
send(reqMsg, "toSensorDeviceManager");
}
Some things I noticed:
There is no printDebugInfo parameter in the PhysicalProcess module. Probably what you are after is collectTraceInfo.
If you just want to update the values some parameters take, it's not a good idea to edit ned files. This is what ini files are for. So instead of changing the default values in ned files, simply assign these values in your ini file. For example, you already assign these parameters in your ini file:
SN.node[*].SensorManager.sensorTypes = "Temperature Bloodglucose"
SN.node[*].SensorManager.corrPhyProcess = "0 1"
You do not need to set them in the ned file as well. Also notice that in the ned file you set the second string as "0,1" not "0 1". The ini file will override the value of the ned file, so what you'll get it "0 1". Fortunately, space separated values is the correct syntax.
You then start defining new .ned .cc and .h files. Why? These do not have any effect. You have not set the variable SN.physicalProcessName in your ini file. This means it takes the default value which is CustomizablePhysicalProcess. You seem to be treating your physical process modules as CustomizablePhysicalProcess because I see you define their parameters inputType and directNodeValueAssignment, which only exist for the CustomizablePhysicalProcess module. So I do not understand what you expect to get by trying to define new physical process modules altogether.
Since you have 2 physical processes, it means that the SensorManager in every node needs to connect to these 2 physical process (the 2 modules that define your physical processes). To do this just set all the parameters of your SensorManager that can be defined as an array (formatted as a space-separated string) as arrays of 2 items.
You can find all relevant parameters in the SensorManager.ned (but do NOT edit the ned file, just set them in your ini file). Here are the parameters just for reference (note that you have already set sensorTypes and corrPhyProcess in your ini file, you just need to also set the rest) :
string pwrConsumptionPerDevice = default ("0.02");
string sensorTypes = default ("Temperature"); // Humidity OR Temperature OR Light
string corrPhyProcess = default ("0"); //holds the indexes of the corresponding phy processes for
//each sensor (usually it should be : "0 1 2 3")
string maxSampleRates = default ("1"); //number of samples per second for each sensor
string devicesBias = default ("0.1"); //If the output signal is not zero when the measured property is zero
string devicesDrift = default (""); //If the output signal slowly changes independent of the
//measured property
string devicesNoise = default ("0.1"); //random deviation of the signal that varies in time
string devicesHysterisis = default (""); //the sensor not instantly follows the change of the property
//being measured and therefore involves the history of the
//measured property
string devicesSensitivity = default ("0"); //holds the minimum value which can be sensed by each sensing device.
string devicesResolution = default ("0.001"); //holds the sensing resolution for each device
I am not sure whether there are other problems with multiple phyProcesses and multiple sensing modalities, because this feature has not been tested in versions after 2.0, so it might not work at all (but hopefully it's a small adjustment to make it work).
Related
I am trying to calculate Mfcc feature in C++. And I found Aubio (https://github.com/aubio/aubio) but I cannot produce same result as Librosa of Python (this is important).
Librosa code:
X, sample_rate = sf.read(file_name, dtype='float32')
mfccs = librosa.feature.mfcc(y=X, sr=sample_rate, n_mfcc=40)
Aubio code:
#include "utils.h"
#include "parse_args.h"
#include <stdlib.h>
aubio_pvoc_t *pv; // a phase vocoder
cvec_t *fftgrain; // outputs a spectrum
aubio_mfcc_t * mfcc; // which the mfcc will process
fvec_t * mfcc_out; // to get the output coefficients
uint_t n_filters = 128;
uint_t n_coefs = 40;
void process_block (fvec_t *ibuf, fvec_t *obuf)
{
fvec_zeros(obuf);
//compute mag spectrum
aubio_pvoc_do (pv, ibuf, fftgrain);
//compute mfccs
aubio_mfcc_do(mfcc, fftgrain, mfcc_out);
}
void process_print (void)
{
/* output times in selected format */
print_time (blocks * hop_size);
outmsg ("\t");
/* output extracted mfcc */
fvec_print (mfcc_out);
}
int main(int argc, char **argv) {
int ret = 0;
// change some default params
buffer_size = 2048;
hop_size = 512;
examples_common_init(argc,argv);
verbmsg ("using source: %s at %dHz\n", source_uri, samplerate);
verbmsg ("buffer_size: %d, ", buffer_size);
verbmsg ("hop_size: %d\n", hop_size);
pv = new_aubio_pvoc (buffer_size, hop_size);
fftgrain = new_cvec (buffer_size);
mfcc = new_aubio_mfcc(buffer_size, n_filters, n_coefs, samplerate);
mfcc_out = new_fvec(n_coefs);
if (pv == NULL || fftgrain == NULL || mfcc == NULL || mfcc_out == NULL) {
ret = 1;
goto beach;
}
examples_common_process(process_block, process_print);
printf("\nlen=%u\n", mfcc_out->length);
del_aubio_pvoc (pv);
del_cvec (fftgrain);
del_aubio_mfcc(mfcc);
del_fvec(mfcc_out);
beach:
examples_common_del();
return ret;
}
Please help to obtain same result of Librosa or suggest any C++ library do this well.
Thanks
This might be what you are looking for: C Speech Features
The library is a complete port of python_speech_features to C and according to the documentation, you should be able to use it in a C++ projects. The results will not be the same of Librosa, here is why but you should be able to work with them.
I want to securely send data to my InfluxDB over the Internet using a NodeMCU MCU and a self signed cert.
I found this library that seems to accomplish exactly this but get compile errors, more below -> https://medium.com/#teebr/iot-with-an-esp32-influxdb-and-grafana-54abc9575fb2
This library seems to only use HTTP -> Am i mistaken?
https://www.arduinolibraries.info/libraries/esp8266-influxdb
Using the example from the 1st library above from TEEBR, i get this error compiling - Any suggestions on how to fix? Will this run on my NodeMCU?
Thanks
C:\Users\Jason\Documents\Arduino\libraries\Influx-Arduino-master\InfluxArduino.cpp:1:24: fatal error: HTTPClient.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
My code
//https://medium.com/#teebr/iot-with-an-esp32-influxdb-and-grafana-54abc9575fb2
#include <WiFi.h>
#include "InfluxArduino.hpp"
#include "InfluxCert.hpp"
InfluxArduino influx;
//connection/ database stuff that needs configuring
char WIFI_NAME[] = "ssid";
const char WIFI_PASS[] = "password!";
const char INFLUX_DATABASE[] = "db_name";
const char INFLUX_IP[] = "10.10.101.101";
const char INFLUX_USER[] = "db_name"; //username if authorization is enabled.
const char INFLUX_PASS[] = "Password"; //password for if authorization is enabled.
const char INFLUX_MEASUREMENT[] = "FromESP8266"; //measurement name for the database. (in practice, you can use several, this example just uses the one)
unsigned long DELAY_TIME_US = 5 * 1000 * 1000; //how frequently to send data, in microseconds
unsigned long count = 0; //a variable that we gradually increase in the loop
void setup()
{
Serial.begin(115200);
WiFi.begin(WIFI_NAME, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
influx.configure(INFLUX_DATABASE,INFLUX_IP); //third argument (port number) defaults to 8086
influx.authorize(INFLUX_USER,INFLUX_PASS); //if you have set the Influxdb .conf variable auth-enabled to true, uncomment this
influx.addCertificate(ROOT_CERT); //uncomment if you have generated a CA cert and copied it into InfluxCert.hpp
Serial.print("Using HTTPS: ");
Serial.println(influx.isSecure()); //will be true if you've added the InfluxCert.hpp file.
}
void loop()
{
unsigned long startTime = micros(); //used for timing when to send data next.
//update our field variables
float dummy = ((float)random(0, 1000)) / 1000.0;
count++;
//write our variables.
char tags[32];
char fields[32];
sprintf(tags,"new_tag=Yes"); //write a tag called new_tag
sprintf(fields,"count=%d,random_var=%0.3f",count,dummy); //write two fields: count and random_var
bool writeSuccessful = influx.write(INFLUX_MEASUREMENT,tags,fields);
if(!writeSuccessful)
{
Serial.print("error: ");
Serial.println(influx.getResponse());
}
while ((micros() - startTime) < DELAY_TIME_US)
{
//wait until it's time for next reading. Consider using a low power mode if this will be a while.
}
}
Long time reader, first time poster - Thanks for all the help in the past!
I am using the LinearMobility module of Inet in a compound module, I need to read the position of the node to use in the .cc code. I have looked for the answers and I came across this code:
cModule *host = getContainingNode(this);
IMobility *mobility = check_and_cast<IMobility *>(host->getSubmodule("mobility"));
... = mobility->getCurrentPosition();
But unfortunately this code throws a run time error, probably there is something wrong with the check_and_cast because the getCurrentPosition() method for the mobility does not work. (I have also tried dynamic_cast instead of check_and_cast bust still the code throws an error ).
The error I receive is :
20:11:54 **** Build of configuration release for project copytic ****
make MODE=release all copytic.cc In file included from copytic.cc:5:
In file included from
C:/Users/Rmin/om/inet4/src\inet/mobility/contract/IMobility.h:27:
C:/Users/Rmin/om/inet4/src\inet/common/geometry/common/Coord.h:307:27:
warning: 'inet::Coord::str' redeclared inline; 'dllimport' attribute
ignored [-Wignored-attributes] inline std::string Coord::str() const
^ In file included from copytic.cc:5: In file included from
C:/Users/Rmin/om/inet4/src\inet/mobility/contract/IMobility.h:28:
C:/Users/Rmin/om/inet4/src\inet/common/geometry/common/EulerAngles.h:77:33:
warning: 'inet::EulerAngles::str' redeclared inline; 'dllimport'
attribute ignored [-Wignored-attributes] inline std::string
EulerAngles::str() const
^ 2 warnings generated. token_m.cc Creating executable: out/clang-release//copytic.exe
out/clang-release//copytic.o:(.text[_ZN7omnetpp14check_and_castIPN4inet9IMobilityENS_7cModuleEEET_PT0_]+0x18):
undefined reference to __imp__ZTIN4inet9IMobilityE'
out/clang-release//copytic.o:(.rdata[_ZTIPN4inet9IMobilityE]+0x18):
undefined reference totypeinfo for inet::IMobility' clang++.exe:
error: linker command failed with exit code 1 (use -v to see
invocation) make: *** [Makefile:102: out/clang-release//copytic.exe]
Error 1
20:12:13 Build Finished (took 18s.781ms)
I also took a shot from the block of code in my source file :
screenshot of the above-mentioned 3 lines of code
As you can see the getCurrentPosition() method does not work, and when I comment 2nd and 3rd lines of the above-mentioned 3 lines of code, simulation runs without any problems.
This is the copytic.cc ( copytic.cc is only used to test the 3 line code in order to get the position of nodes and does not have any other purposes ) :
#include <string.h>
#include <omnetpp.h>
#include "token_m.h"
#include "inet/mobility/contract/IMobility.h"
using namespace omnetpp;
using namespace std;
using namespace inet;
class Txc1 : public cSimpleModule
{
public :
simtime_t delay = 0.5 ;
simtime_t delay2 = 0.5 ;
simtime_t duration = 0.25 ;
int maxnodes = 10 ;
string x[10] = {"tic", "toc", "tic"} ;
int numnodes = 2;
int freenodeflag = 1;
string successor ;
string predecessor ;
int inring = 0 ;
string posx ;
protected:
// The following redefined virtual function holds the algorithm.
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
// The module class needs to be registered with OMNeT++
Define_Module(Txc1);
void Txc1::initialize()
{
WATCH(x[0]);
WATCH(x[1]);
WATCH(x[2]);
WATCH(x[3]);
WATCH(successor);
WATCH(numnodes);
WATCH(y);
WATCH(posx);
Token *msgt = new Token("tok");
msgt->setRingorder(0, "tic");
successor="toc";
predecessor="toc";
cModule *target = getModuleByPath("Tictoc1.toc");
sendDirect(msgt, delay , duration , target , "radioIn");
inring = 1 ;
}
void Txc1::handleMessage(cMessage *msg)
{
cModule *host = getParentModule()->getSubmodule("tec")->getSubmodule("mobility");
IMobility *mmobility = check_and_cast<IMobility *>(host);
Coord pos = mmobility->getCurrentPosition();
if (strcmp("tok", msg->getName()) == 0 ) {
Token *inv1 = new Token("tok");
Token *inv2 = new Token("tok");
Token *inv3 = new Token("tok");
cModule *targetinv1 = getModuleByPath("Tictoc1.tic");
cModule *targetinv2 = getModuleByPath("Tictoc1.toc");
cModule *targetinv3 = getModuleByPath("Tictoc1.tec");
sendDirect(inv1, delay , duration , targetinv1 , "radioIn");
sendDirect(inv2, delay , duration , targetinv2 , "radioIn");
sendDirect(inv3, delay , duration , targetinv3 , "radioIn");
}
}
I am working on project, and we need to establish a CAN communication between 4 nodes, 2 using a PIC 18F4580 and 2 using 18F25K80. In all those circuits, I'm using a Crystal oscillator 20MHz. The issue is when I test the communication between same PICs, it's working, but when I try with two different PICs it's not working.
The codes I used to test:
For the emitting PIC 18F4580 : Emitting a CAN message every 1 second :
int i;
unsigned char Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags; // can flags
unsigned char Rx_Data_Len; // received data length in bytes
char RxTx_Data[8]; // can rx/tx data buffer
char Msg_Rcvd; // reception flag
const long ID_cmd = 3, ID_led1 = 2; // node IDs
long Rx_ID;
void main() {
ADCON1=0xF;
TRISA=0xFF;
TRISD=0;
PORTD=0;
for(i=0;i<10;i++) {
PORTD=0xFF ^ PORTD; //Blinking Leds
Delay_ms(100);
}
Can_Init_Flags = 0; //
Can_Send_Flags = 0; // clear flags
Can_Rcv_Flags = 0; //
Can_Send_Flags = _CAN_TX_PRIORITY_0 & // form value to be used
_CAN_TX_XTD_FRAME & // with CANWrite
_CAN_TX_NO_RTR_FRAME;
Can_Init_Flags = _CAN_CONFIG_SAMPLE_THRICE & // form value to be used
_CAN_CONFIG_PHSEG2_PRG_ON & // with CANInit
_CAN_CONFIG_XTD_MSG &
_CAN_CONFIG_DBL_BUFFER_ON &
_CAN_CONFIG_VALID_XTD_MSG;
CANInitialize(1,3,3,3,1,Can_Init_Flags); // Initialize CAN module
CANSetOperationMode(_CAN_MODE_NORMAL,0xFF); // set NORMAL mode
for(i=0;i<10;i++) {
PORTD=0xFF ^ PORTD; //Blinking Leds
Delay_ms(100);
}
while(1){
PORTD.F7=PORTA.F0;
PORTD.F6=PORTA.F1;
PORTD.F5=PORTA.F2;
PORTD.F4=PORTA.F3; //LEDS := SWITCHS
CANWrite(ID_cmd, RxTx_Data, 1, Can_Send_Flags); // send incremented data back
Delay_ms(1000);
}
}
For the receiving Node PIC 18F25K80 : Blink after receiving any CAN message (Should blink every 1 second) :
unsigned char Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags; // can flags
unsigned char Rx_Data_Len; // received data length in bytes
char RxTx_Data[8]; // can rx/tx data buffer
char Msg_Rcvd; // reception flag
const long ID_led1 = 2, ID_cmd = 3; // node IDs
long Rx_ID;
void main() {
//OSCCON |= 0b01110010;
TRISC = 0;
Can_Init_Flags = 0; //
Can_Send_Flags = 0; // clear flags
Can_Rcv_Flags = 0; //
Can_Send_Flags = _CAN_TX_PRIORITY_0 & // form value to be used
_CAN_TX_XTD_FRAME & // with CANWrite
_CAN_TX_NO_RTR_FRAME;
Can_Init_Flags = _CAN_CONFIG_SAMPLE_THRICE & // form value to be used
_CAN_CONFIG_PHSEG2_PRG_ON & // with CANInit
_CAN_CONFIG_XTD_MSG &
_CAN_CONFIG_DBL_BUFFER_ON &
_CAN_CONFIG_VALID_XTD_MSG;
CANInitialize(1,3,3,3,1,Can_Init_Flags); // Initialize CAN module
CANSetOperationMode(_CAN_MODE_CONFIG,0xFF); // set CONFIGURATION mode
CANSetMask(_CAN_MASK_B1,-1,_CAN_CONFIG_XTD_MSG); // set all mask1 bits to ones
CANSetMask(_CAN_MASK_B2,-1,_CAN_CONFIG_XTD_MSG); // set all mask2 bits to ones
CANSetFilter(_CAN_FILTER_B2_F4,ID_cmd,_CAN_CONFIG_XTD_MSG);// set id of filter B2_F4 to 2nd node ID
CANSetOperationMode(_CAN_MODE_NORMAL,0xFF); // set NORMAL mode
while(1) { // endless loop
Msg_Rcvd = CANRead(&Rx_ID , RxTx_Data , &Rx_Data_Len, &Can_Rcv_Flags); // receive message
if ((Rx_ID == ID_cmd) && Msg_Rcvd) { // if message received check id
PORTC.F3=!PORTC.F3;
}
}
}
Any help would be greatly appreciated, thanks.
It's me again, it worked, the nodes must have the same oscillator value (in my case : 20MHz Crystal).
I'm trying to write a program that takes a value in the Fahrenheit scale, validates the value to ensure that it is legitimate, and returns the proper value for Fahrenheit, Celsius, and Newton.
The code below keeps giving error messages for Lines 21, 25, 29 (The void's)
#include <iostream>
using namespace std;
class temperature {
public:
double getFahrenheit();
double getCelsius();
double getNewton();
void setFahrenheit();
void setCelsius();
void setNewton();
private:
double fahrenheit, Celsius;
double c, f;
};
void freezing.setFahrenheit(){
f = 32;
fahrenheit = f;
}
void freezing.setCelsius(){
c = (5.0/9.0) * ( f - 32);
celsius = c;
}
void freezing.setNewton(){
n=(33.0/100.0)*c;
newton=n;
double freezing.getFahrenheit(){
return fahrenheit;
}
double freezing.getCelsius(){
return Celsius;
}
Double freezing.getNewton(){
Return Newton;
}
int main() {
Temperature freezing(32);
Freezing.setFahrenheit(); Freezing.setCelsius();
Freezing.setNewton();
cout << "water freezes at " << freezing.getFahrenheit() << " Fahrenheit, " << freezing.getCelsius() << " Celisus, and " << freezing.getNewton() << " Newton" << endl;
return 0;
}
You need to use :: instead of . Moreover, your class is called temperature and not freezing
void temperature::setFahrenheit()
See also this question
There's a few other errors too:
void temperature::setCelsius(){ //and not void freezing.setCelsius
c = (5.0/9.0) * ( f - 32);
celsius = c;
}
Here you reference celsius , but the temperature class defines Celsius with a captial C.
void freezing.setNewton(){
n=(33.0/100.0)*c;
newton=n;
Here you use the n and newton variables, but you have not defined them anywhere. They should perhaps be members of your temperature class.
Double freezing.getNewton(){
Return Newton;
}
Here you have capital letters, which doesn't make sense, it should be
double temperature::getNewton(){
return newton; //you need to make this a member variable of your class too..
}
Temperature freezing(32);
Your temperature class has a lowercase t , the Temperature class doesn't exist.
And there's no constructor defined, so you can't pass 32 in there.
Freezing.setFahrenheit();
Freezing.setCelsius();
These 2 lines references Freezing, but you called your variable freezing