As part of a project my group has to program an Arduino to get a signal from an RFID, and pass data into Processing depending on said signal. For example, when a tag is sensed by the Arduino, String data would be passed into Processing and handled there.
We have the Arduino part working but Processing is throwing up errors. In our project we must wait for user input at certain points.
public int readRFID()
{
int tagNumber = 0;
//Has to be contained in try/catch because of errors with null
try
{
if ( myPort.available() > 0) { // If data is available,
val = myPort.readStringUntil('\n');
} // read it and store it in val
//Convert val into integer and set to tagNumber
tagNumber = Integer.parseInt(val);
}
//An error occurs if val is null, which is the case every time unless it actually gets data
catch(Exception e)
{
tagNumber = 0;
}
return tagNumber;
}
At the end, tagNumber should be returned as either 0 or a positive value (when a tag is present and there is a number to be read in). In the method that calls this method we have this:
//RFID SCANNING GOES HERE
int tag = 0;
while (tag == 0)
{
//When RFID reads as null, this method should return 0 until a tag
//is read in
tag = readRFID();
}
//userChoice is set to the number read in -1 because tags are numbered 1, 2, 3, 4
//but userChoice will refer to an index in an array that starts at 0
userChoice = tag - 1;
We are not sure why this code isn't working - all we're sure of is that the method has to be continuously called until a tag is present. Any suggestions would be greatly appreciated.
Related
I'm in the process of creating a QT application which is using multiple (14) qcheckboxes. I need to have a limit (preferably set as a variable that i can change) to the number of checkboxes that can be checked at the same time, is there any way to achieve this cleanly ? Thanks for your time.
There is no simple way of doing this, you have to write your code to do it.
I suppose you have the checkboxes in some parent widget class. So I would create a slot which looks like this.
void SomeParentWidget::onCheckBoxToggled(bool value)
{
// when we unchecked the checkbox,
// we do not need to count the number of checked ones
if (!value)
return;
int total = 0;
int limit = 15; // your "magic" number of maximum checked checkboxes
for (auto chb : allCheckBoxes()) // allCheckBoxes() is some method which returns all the checkboxes in consideration
{
if (chb->isChecked())
{
++total;
if (total > limit)
{
// too many checkboxes checked! uncheck the sender checkbox
// Note: you may want to add some nullptr checks or asserts to the following line for better robustness of your code.
qobject_cast<QCheckBox*>(sender())->setChecked(false);
return;
}
}
}
}
And when creating each of your checkboxes inside some parent widget, connect this slot to their signal:
auto chb = new QCheckBox();
connect(chb, &QCheckBox::toggled, this, &SomeParentWidget::onCheckBoxToggled);
Implementation of allCheckBoxes() is up to you, I do not know how you can retrieve the collection of all your check boxes. Depends on your design.
I found another, even simpler solution. Use this slot.
void SomeParentWidget::onCheckBoxToggled(bool value)
{
static int totalChecked = 0; // static! the value is remembered for next invocation
totalChecked += value ? 1 : -1;
Q_ASSERT(totalChecked >= 0);
int maxChecked = 15; // any number you like
if (value && totalChecked > maxChecked)
{
qobject_cast<QCheckBox*>(sender())->setChecked(false);
}
}
... and connect it to checkboxes' toggled() signal. Note that in order to work correctly, all check boxes must be unchecked at the time when you make the signal-slot connection because this function starts counting from zero (0 is the initial value of the static variable).
You can store all your checkboxes in a map (either in an std::map, an std::unordered_map or an QMap). Your keys will be your checkboxes, and your values will be their states, so something like this:
std::unordered_map<QCheckBox*, bool> m_checkBoxStates;
Here's what your connected to your toggled signal of all your checkboxes look like (keep in mind that all the signals will be connected to the same slot):
void MainWindow::onToggled(bool checked) {
QCheckBox* checkBox = sender(); //the checkbox that has been toggled
m_checkBoxStates[checkBox] = checked;
if (!checked) {
return;
}
const int count = std::count_if(m_checkBoxStates.begin(), m_checkBoxStates.end(),
[](const auto pair) {
return pair.second == true;
});
if (count > maxCount) {
checkBox->setChecked(false);
}
}
I am writing code for a school project that will be used for a Chromebook charging station with security. The problem I am having now is when I am detecting if a Chromebook is actually in the slot after the user has been assigned one, I am using a rocker switch to simulate this but when I am declaring the pin to the rocker, the arduino verfier comes up with that
"'slot1' does not name a type".
Code is below:
//class
class Chromebook_slot {
public:
String Name = "";
String RFID_tag = "";
int rocker = 0;
boolean chromebook_in = false;
//class function to check if chromebook is in.
//if not, redirect already to reassigning so chromebook slot is entered as open and free.
void set_if_in()
{
int momen_1_state = digitalRead(momen_1);
int momen_2_state = digitalRead(momen_2);
// the button has been pushed down and the previous process has been completed
// eg. servos would have been reset if there was a previous user
if (momen_1_state == HIGH || momen_2_state == HIGH)
{
chromebook_in = digitalRead(this->rocker);
if (chromebook_in == 0)
{
re_assigning();
}
else
{
return;
}
}
}
};
//this is now outside the class..
//class declarations
Chromebook_slot slot1;
Chromebook_slot slot2;
//variables for rocker switches which will act for detecting chromebooks.
// in my final version, this will replaced by a photoresistor and laser.
slot1.rocker = 3;
slot2.rocker = 2;
Where the function re_assigning() is a separate function declared further in the code and just resets the slot as open for future use.
slot1.rocker = 3;
slot2.rocker = 2;
These are statements that cannot be at the top level of a C++ (or .ino) file. They need to be inside of a function. What's happening is the compiler is looking looking at the slot1 identifier through the lens of potential valid constructions. It sees an identifier, and about the only thing that could legally exist at this point in the code that starts with an identifier like that is some declaration, e.g. int a = 7;, or more abstractly some_type some_more_stuff. So it expects slot1 to be a type, which it isn't, hence the message.
If you want an assignment like those to happen early on in an Arduino program, the simplest thing you could do is put them in setup():
void setup() {
slot1.rocker = 3;
slot2.rocker = 2;
// ...
}
Or, you'd make these part of the Chromebook_slot's constructor, such that they could be given in slot1 and slot2's declaration:
class Chromebook_slot {
public:
Chromebook_slot(int rocker_init_value) {
rocker = rocker_init_value;
}
// ...
Or in a maybe less familiar but more proper form, using the constructor's initialization list:
class Chromebook_slot {
public:
Chromebook_slot(int rocker_init_value)
: rocker(rocker_init_value) {}
// ...
Once you have a constructor for Chromebook_slot, your variables can become:
Chromebook_slot slot1(3);
Chromebook_slot slot2(2);
Using GraphEdit, I can add the filter to the editor and use it to render a video. When I create the instance via COM (using DirectShow.NET), the method EnumPins (followed by Next checks) returns no pins.
Is there a reason why GraphEdit would show the pins and I cannot get a reference to the pins via the COM interfaces?
EDIT: Here is the method I am using to get the first available pin (of any type). Nothing is ever returned for this filter, but I can see 4 pins (two in, two out) in graph edit.
public static IPin GetPins(IBaseFilter vSource, int iIndex)
{
IEnumPins pins;
var ppPins = new IPin[1];
if (vSource == null)
return null;
DsError.ThrowExceptionForHR(vSource.EnumPins(out pins));
try
{
while (pins.Next(1, ppPins, IntPtr.Zero) == 0)
{
return ppPins[0];
}
}
finally
{
Marshal.ReleaseComObject(pins);
}
return null;
}
I have direct show filter which takes an input and process it and give the result to outputpin.
I want to write this filter output data to a file...And i want to do it in its filter class.So i want to get the output pin buffer data.
Shortly how to reach final data of outputpin in its filter? How can i do it?
Not: The output pin is derived from CBaseOutputPin.This is an open source filter it "magically" :-) put wright data to its output pin which i can not figure out how yet...
Update:
Here is the siutuation:
Media Source ----> GFilter ----> FileWriter
I have source code of GFilter... I have no source code of FileWriter...What i want to make is make GFilter write its own data...I debug GFilter get some insight how its transform data but my attemp to write this data result with wrong data... So i deceide for now how to simply get data at its output pin...
Update[2]
In Filter outputpin somwhere the filter writer pass the file writer pin to IStreamPtr variable...Everthing seems to written to a variable m_pIStream which is type of [IStreamPtr]
GFilterOutput::CompleteConnect(IPin *pReceivePin)
{
// make sure that this is the file writer, supporting
// IStream, or we will not be able to write out the metadata
// at stop time
// m_pIStream is IStreamPtr type
m_pIStream = pReceivePin;
if (m_pIStream == NULL)
{
return E_NOINTERFACE;
}
return CBaseOutputPin::CompleteConnect(pReceivePin);
}
...
GFilterOutput::Replace(LONGLONG pos, const BYTE* pBuffer, long cBytes)
{
//OutputDebugStringA("DEBUG: Now at MuxOutput Replace");
// all media content is written when the graph is running,
// using IMemInputPin. On stop (during our stop, but after the
// file writer has stopped), we switch to IStream for the metadata.
// The in-memory index is updated after a successful call to this function, so
// any data not written on completion of Stop will not be in the index.
CAutoLock lock(&m_csWrite);
HRESULT hr = S_OK;
if (m_bUseIStream)
{
IStreamPtr pStream = GetConnected();
if (m_pIStream == NULL)
{
hr = E_NOINTERFACE;
} else {
LARGE_INTEGER liTo;
liTo.QuadPart = pos;
ULARGE_INTEGER uliUnused;
hr = m_pIStream->Seek(liTo, STREAM_SEEK_SET, &uliUnused);
if (SUCCEEDED(hr))
{
ULONG cActual;
hr = m_pIStream->Write(pBuffer, cBytes, &cActual);
if (SUCCEEDED(hr) && ((long)cActual != cBytes))
{
hr = E_FAIL;
}
}
}
} else {
// where the buffer boundaries lie is not important in this
// case, so break writes up into the buffers.
while (cBytes && (hr == S_OK))
{
IMediaSamplePtr pSample;
hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0);
if (SUCCEEDED(hr))
{
long cThis = min(pSample->GetSize(), cBytes);
BYTE* pDest;
pSample->GetPointer(&pDest);
CopyMemory(pDest, pBuffer, cThis);
pSample->SetActualDataLength(cThis);
// time stamps indicate file position in bytes
LONGLONG tStart = pos;
LONGLONG tEnd = pos + cThis;
pSample->SetTime(&tStart, &tEnd);
hr = Deliver(pSample);
if (SUCCEEDED(hr))
{
pBuffer += cThis;
cBytes -= cThis;
pos += cThis;
}
}
}
}
return hr;
}
You have full source code, step it through with debugger until you reach the point where your filter calls IPin::Receive of the peer downstream filter, update/override code there and you have full control as for writing data into file etc.
I am using serial port to read the data off the scale that is attached to the thin client. In 99% of cases the data is read correctly - ie whatever is on the scale is what is captured by the application.
However, sometimes, it looks like data is dropped. For instance instead of 90.007 it will be read as 0.007. I am using ReadLine function:
private void CaptureWeight()
{
globalCounter++;
string value = "";
_sp.DiscardInBuffer();
while (!this._processingDone)
{
try
{
value = this._sp.ReadLine();
if (value != "")
{
if (value == "ES")
{
_sp.DiscardInBuffer();
value = "";
}
else
{
this.Invoke(this.OnDataAcquiredEvent, new object[] { value });
}
}
}
catch (TimeoutException)
{
//catch it but do nothing
}
catch
{
//reset the port here?
MessageBox.Show("some other than timeout exception thrown while reading serial port");
}
}
} //end of CaptureWeight()
Don't call DiscardInBuffer. The operating system buffer is filled asynchronously as data is shifted in through the UART. Read all of the data and act on it accordingly because you have no way of knowing what is in the buffer at the time you discard it!
When does "ES" come? It is theory possible that the value immediately after "ES", is not read correctly, because you call DiscardInBuffer(). If in that time the buffer contains part of the next reading, e.g. the 9 in 90.007, the 9 gets discarded and you read 0.007.
Try discarding only everything before the last CR LF. But leave incomplete lines.